• 自定义方法
    • HTTP映射
    • 使用场景
    • 常见自定义方法

    自定义方法

    本章将会讨论如何在API设计中使用自定义方法。

    自定义方法指的是五个标准方法之外的API方法。他们应当仅用于标准方法不易表达的功能。一般而言,API设计者应当尽可能优先考虑使用标准方法,而不是自定义方法。标准方法相对更简单,定义完善的语义,并且开发者也更加熟悉;这使标准方法更易用,并且使用者更难犯错。使用标准方法的另一个优势是API平台会有更好的支持,如计费、错误处理、日志、监控等等。

    自定义方法可以跟资源、集合或者服务关联。它可以接受任意请求,并返回任意结果;并支持流式的请求与结果。

    HTTP映射

    对于自定义方法,它们应该使用以下形式的HTTP映射

    1. https://service.name/v1/some/resource/name:customVerb

    使用:而不是/符号去分隔自定义动词跟资源名,可以让我们支持任意路径。比方说取消删除一个文件可以映射为POST /files/a/long/file/name:undelete

    选择HTTP映射时,应当应用以下准则:

    • 自定义方法应该使用HTTP POST,因为它含有最灵活的语义。
    • 自定义方法可以使用其它HTTP动词(参考以下章节),但方法需要遵从该动词的标准HTTP语义。
    • 请注意,使用HTTP GET的自定义方法必须是幂等并且无副作用。比方说,支持资源特定视图的自定义方法可以用HTTP GET
    • 对应于资源名或者资源集合名的请求消息字段应当映射为URL路径
    • URL路径必须以冒号 + 自定义动词结尾
    • 如果HTTP动词允许请求体消息(如 POST, PUT, PATCH, 或者其它HTTP动词),那么自定义方法的HTTP配置必须使用body: "\*",并且其它所有剩余的请求消息自动应当映射到请求体中。(译者注:TODO)
    • 如果HTTP动词不允许请求体消息(如 GET, DELETE),那么自定义方法的HTTP配置就绝不可以使用body,并且其它所有剩余的请求消息字段自动应当映射到URL查询参数中。

    警告:如果一个服务实现了多套API,API的生产者必须谨慎的创建服务配置,以避免API之间的自定义动词相互冲突。

    1. // 这是一个服务级别的自定义方法。
    2. rpc Watch(WatchRequest) returns (WatchResponse) {
    3. // 自定义方法映射到HTTP POST。所有请求参数通过body传递。
    4. option (google.api.http) = {
    5. post: "/v1:watch"
    6. body: "*"
    7. };
    8. }
    9. // 这是一个资源集合级别的自定义方法。
    10. rpc ClearEvents(ClearEventsRequest) returns (ClearEventsResponse) {
    11. option (google.api.http) = {
    12. post: "/v3/events:clear"
    13. body: "*"
    14. };
    15. }
    16. // 这是一个资源级别的自定义方法。
    17. rpc CancelEvent(CancelEventRequest) returns (CancelEventResponse) {
    18. option (google.api.http) = {
    19. post: "/v3/{name=events/*}:cancel"
    20. body: "*"
    21. };
    22. }
    23. // 这是批量获取的自定义方法。
    24. rpc BatchGetEvents(BatchGetEventsRequest) returns (BatchGetEventsResponse) {
    25. // 批量获取方法映射到HTTP GET
    26. option (google.api.http) = {
    27. get: "/v3/events:batchGet"
    28. };
    29. }

    使用场景

    某些场景下,自定义方法是合理的选择:

    • 重启一台虚拟机 另外一种实现方式是:”在重启集合中创建一个新的重启资源”,这让人感觉繁冗的过份。又或者是”虚拟机有客户端能从运行中跟重启中切换的可变状态”?这又会让人困惑是否还其他潜在的状态改变。重启是一个被广泛接受的概念,直接将其设为一个自定义方法,是符合开发者预期的。
    • 发送邮件 创建一封电子邮件并不意味着要发送它,也可以仅是存为草稿。比较起其它的设计方式(把邮件移动到”发件箱”集合中),自定义方法的优势是更容易被API使用者察觉,建模也更直接。
    • 提拔一位同事 (corpeng) 如果使用标准Update方法,客户端需要复制企业提拔流程中的管理政策,以确保提拔是在正确的等级,并属于同一职业阶梯等等。
    • 批处理的方法对于性能关键方法,可以提供自定义批处理方法以减少每次请求开销。例如,accounts.locations.batchget。

    有的时候,标准方法则比自定义方法更适用:

    • 使用不同的参数查询资源 (使用标准list方法,跟标准list过滤)。
    • 简单资源属性修改(使用update方法跟字段掩码)。
    • 关闭一个通知(使用标准delete方法)。

    常见自定义方法

    API设计者应当考虑使用以下一些常见或者有用的自定义方法名;而不是直接定义新的名字,以提高不同API之间的一致性。

    方法名 自定义动词 HTTP动词 备注
    Cancel :cancel POST 取消一个未完成的操作(构建,计算等等)
    BatchGet :batchGet GET 批量获取多个资源(查阅List标准方法中的详细描述)
    Move :move POST 将一个资源从一个父级移到另一个
    Search :search GET List的语义不足够时,搜索获取数据
    Undelete :undelete POST 恢复之前删除的数据;推荐的数据的保留时间是30天。