Google AIPs 小记

本文介绍了Google的API改进提案(AIPs),涵盖了标准操作、特殊接口、修订管理以及设计原则。强调了方便调用方使用、统一规范、幂等性和安全性。讨论了如批量操作、长运行任务、资源历史记录(修订接口)以及错误处理的细节,旨在提升API设计的质量和用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Read the latest article and comment on Notion.

API Improvement Proposals

  • API 的大致分类

    • Standard methods: GET / List / Create / Update / Delete
    • Standard methods 和其他methods 的 batch operations
    • Standard methods 和其他methods 的 long-running operations
    • Jobs 接口
    • Import and export 数据接口
    • item method / collection method / db method / stateless method

    特殊接口

    • Revision 接口,一个资源的历史记录,之所以叫’revision’,是为了和API 的‘version’ 区分开
      • get,记得在返回的name 里加上revision id。

      • tag,给一个revision 加上human readable 的标签,之后revision id 和tag 都能用来get revision。

      • list

      • commit,基于最新版本的resource 创建revision,可以在一些条件下自动创建,也可以开放出来把时机判断交给用户。

      • rollback,把某个revision 设置成线上最新的数据。

      • delete。可以导致线上resource 变化,但是不能导致resource 被删除,当被删除的revision 是最后一个revision 时,应拒绝请求。

      • child revision。适当考虑一个资源下的某个子资源也有revision 的需求。

    • Purge 接口,当需要删除的数据量级超过Batch Delete 语义,考虑使用Purge
      • 支持使用 filter 来筛选出更多的资源,但是因为数量过大没必要返回。
      • 只有当 request 的 force == true 时才执行删除。
      • response 要返回 purge_count
      • 当request force == false 时,返回purge_count 和约100个 purge_sample
  • AIPs 体现出的设计原则

    **方便外界调用方的使用。**一些原则对内部API 要求过高了。

    • 统一规范:doc 详细cover 了很多细节。
      • 比如每个resource response 的第一个field 都得是 canonical name,无论request。
        • 对于collections response,则是 parent ,不是 name
      • 分页只返回 page_token 不返回 offset
        • token 可以代表更多信息。
        • 防止用户解析分页的内部逻辑,给接口更新带来灵活性。
        • token 一般3天后过期
      • order_by 字段也用string ,保证灵活性。
      • update 只能用 PATCHPUT 有可能会破坏兼容性。
        • PUT 代表全替换,有时候客户端觉得一个对象的fields 是旧的 F F F,但可能服务端已经是新的 F ′ F^{'} F了, 这时就出错了。
      • 强一致性就用 etag ,服务端生成下放给客户端,客户端更新时带上 etag (乐观锁
      • 幂等性就用 request_id ,客户端生成发给服务端,表示相关的请求是同一个,请求幂等。
      • 预计执行时间超过10秒的方法返回query id而不是结果,保持运行结果30天内可查询。
      • startend 表示 [, ) 数组; firstlast 表示 [, ] 数组。
      • 错误信息不应该假设用户知道API 的底层实现细节,brief but actionable。
        • 如果需要更多的信息,考虑提供一个link where a reader can get more information or ask questions to help resolve the issue.
        • 错误信息应该提供足够机器理解的数据,如果没有。改变错误信息的 string message 也应该被考虑为 a backwards-incompatible change.
        • 尽量不要提供部分错误部分正确的response,会给用户解析带来困难。
      • state 而不是 status ,和HTTP 状态做区分。
    • 在全面的规则外侧建立灵活性:
      • id 可以有alias,例如用 me 替代当前用户的id。
      • enum 只适用于枚举值变化不频繁的情况,变化频繁还是用string。
        • 以及只要变化频繁都更使用string,没有过多的强类型限制。
      • 没有必要说update 需返回被更新对象的所有field,如果一个field计算昂贵,那也没必要在更新完就计算,但是update masks 里面cover 的field 还是一定要返回。
      • Partial response 可以用 view enumeration (事先定义好不同的view 选项,比如 BASIC 或者 FULL ),也可以用read masks。
    • 保证安全调用
      • update 尽量只更新对象的数据本身,side effects should be triggered by custom methods.
      • 删除要用 force field,没有 force == true 就要执行足够多的安全检查。
      • 对一个数据的collection field 更新需考虑添加单独的 AddRemove 方法,直接替换数组容易导致错误,或者用 etag 保证强一致性。
      • 对 singleton resources (一个parent 只有一个的resource),不可以有 Create List Delete 方法,这些应该让parent 负责。
      • validate_only 字段,为写接口提供dry run 语义。
      • soft delete, show_deleted 字段 和相应的 Undelete 接口。
        • 还可以加上30天后自动删除的机制。
    • API 设计关注结果,命名尽量抛弃不必要的修饰词,力求直观好记,对使用方友好。
    • control planedata plane 之间用不同资源划清楚边界。
      • Control plane operations are responsible for managing the lifecycle of resources. (row level)
      • Data plane operations are responsible for managing the content of resources. (DB level)
  • 提供了一些magic number “经验之谈”

    • 分页token 一般三天后过期
    • 预计执行时间超过10秒的方法返回query id而不是结果,保持运行结果30天内可查询。
    • soft delete 在30天后才真正删除。
    • Beta 版本转成stable 版的时间一般是90天。
  • 附:AIPs 的命名规范

    Repeated fields

    Repeated fields must use the proper plural form, such as books or authors. On the other hand, non-repeated fields should use the singular form such as book or author. This implies that resource names should use the singular form as well, since the field name should follow the resource name (e.g., use repeated Book booksnot Books books = 1).

    Prepositions

    Field names should not include prepositions (such as “with”, “for”, “at”, “by”, etc). For example:

    • error_reason (not reason_for_error)
    • author (not written_by)

    It is easier for field names to match more often when following this convention. Additionally, prepositions in field names may also indicate a design concern, such as an overly-restrictive field or a sub-optimal data type. This is particularly true regarding “with”: a field named book_with_publisherlikely indicates that the book resource may be improperly structured and worth redesigning.

    Adjectives

    For consistency, field names that contain both a noun and an adjective should place the adjective beforethe noun. For example:

    • collected_items (not items_collected)
    • imported_objects (not objects_imported)

    Booleans

    Boolean fields should omit the prefix “is”. For example:

    • disabled (not is_disabled)
    • required (not is_required)

    String vs. bytes

    When using bytes, the contents of the field are base64-encoded when using JSON on the wire. Services should use bytes when there is a need to send binary contents over the wire, and should not ask the user to manually base64-encode a field into a string field.

    URIs

    Field names representing URLs or URIs should always use uri rather than url. This is because while all URLs are URIs, not all URIs are URLs. Field names may use a prefix in front of uri as appropriate.

    Reserved words

    Field names should avoid using names that are likely to conflict with keywords in common programming languages, such as newclassfunctionimport, etc. Reserved keywords can cause hardship for developers using the API in that language.

    Conflicts

    Messages should not include a field with the same name as the enclosing message (ignoring case transformations). This causes conflicts when generating code in some languages.

    Display names

    Many resources have a human-readable name, often used for display in UI. This field should be called display_name, and should not have a uniqueness requirement.

    If an entity has an official, formal name (such as a company name or the title of a book), an API may use title as the field name instead. The title field should not have a uniqueness requirement.

    Quantities

    Quantities with a clear unit of measurement (such as bytes, miles, and so on) must include the unit of measurement as the suffix. When appropriate, units should use generally accepted abbreviations (for example, distance_km rather than distance_kilometers).

    // A representation of a non-stop air route.
    message Route {
      // The airport where the route begins.
      string origin = 1;
    
      // The destination airport.
      string destination = 2;
    
      // The distance between the origin and destination airports.
      // This value is also used to determine the credited frequent flyer miles.
      int32 distance_miles = 3;
    }
    

    If the quantity is a number of items (for example, the number of nodes in a cluster), then the field shoulduse the suffix _count (not the prefix num_):

    // A cluster of individual nodes.
    message Cluster {
      // The number of nodes in the cluster.
      int32 node_count = 1;
    }
    

    Note: Fields must not use unsigned integer types, because many programming languages and systems do not support them well.

    Resource names and IDs

    name

    Every resource must have a string name field, used for the resource name (AIP-122), which should be the first field in the resource.

    parent

    The string parent field refers to the resource name of the parent of a collection, and should be used in most List (AIP-132) and Create (AIP-133) requests.

    uid

    The output only string uid field refers to a system-assigned, unique identifier for a resource. When provided, this field should be a UUID4Declarative-friendly resources should include this field.

    Other names

    display_name

    The string display_name field must be a mutable, user-settable field where the user can provide a human-readable name to be used in user interfaces. Declarative-friendly resources should include this field.

    Display names should not have uniqueness requirements, and should be limited to <= 63 characters.

    title

    The string title field should be the official name of an entity, such as a company’s name. This is a more formal variant of string display_name.

    given_name

    The string given_name field must refer to a human or animal’s given name. Resources must not use first_name for this concept, because the given name is not placed first in many cultures.

    family_name

    The string family_name field must refer to a human or animal’s family name. Resources must not use last_name for this concept, because the family name is not placed last in many cultures.

    Timestamps

    create_time

    The output only google.protobuf.Timestamp create_time field must represent the timestamp when the resource was created. This may be either the time creation was initiated or the time it was completed. Declarative-friendly resources should include this field.

    update_time

    The output only google.protobuf.Timestamp update_time field must represent the timestamp when the resource was most recently updated. Any change to the resource made by users must refresh this value; changes to a resource made internally by the service may refresh this value. Declarative-friendly resources should include this field.

    delete_time

    The output only google.protobuf.Timestamp delete_time field must represent the timestamp that a resource was soft deleted. This may correspond to either the time when the user requested deletion, or when the service successfully soft deleted the resource. If a resource is not soft deleted, the delete_time field must be empty.

    Resources that support soft delete (AIP-164should provide this field.

    expire_time

    The google.protobuf.Timestamp expire_time field should usually represent the time when a soft deleted resource will be purged from the system. It may be used for similar forms of expiration as described in AIP-214. Resources that support soft delete should include this field.

    In some situations, it can be difficult to provide an exact expire_time value, because of implementation dependencies. Services may provide an expire_time value that is inexact, but the resource must not be expired from the system before that time.

    Resources that support soft delete (AIP-164should provide this field.

    Descriptions

    • What is it?
    • How do you use it?
    • What does it do if it succeeds? What does it do if it fails?
    • Is it idempotent?
    • What are the units? (Examples: meters, degrees, pixels)
    • What are the side effects?
    • What are common errors that may break it?
      • What is the expected input format?
      • What range of values does it accept? (Examples: [0.0, 1.0)[1, 10])
        • Is the range inclusive or exclusive?
      • For strings, what is the minimum and maximum length, and what characters are allowed?
        • If a value is above the maximum length, do you truncate or send an error?
    • Is it always present? (Example: “Container for voting information. Present only when voting information is recorded.”)
    • Does it have a default setting? (Example: “If page_size is omitted, the default is 50.”)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值