自定义方法

本章将会讨论如何在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天。