自定义方法

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

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

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

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

    • 自定义方法应该使用HTTP POST,因为它含有最灵活的语义。
    • 自定义方法可以使用其它HTTP动词(参考以下章节),但方法需要遵从该动词的标准。
    • 请注意,使用HTTP GET的自定义方法必须是幂等并且无副作用。比方说,支持资源特定视图的自定义方法可以用HTTP GET
    • 对应于资源名或者资源集合名的请求消息字段应当映射为URL路径
    • URL路径必须以冒号 + 自定义动词结尾
    • 如果HTTP动词允许请求体消息(如 POST, PUT, PATCH, 或者其它HTTP动词),那么自定义方法的HTTP配置必须使用body: "\*",并且其它所有剩余的请求消息自动应当映射到请求体中。(译者注:TODO)
    • 如果HTTP动词不允许请求体消息(如 GET, DELETE),那么自定义方法的HTTP配置就绝不可以使用body,并且其它所有剩余的请求消息字段自动应当映射到URL查询参数中。
    1. // 这是一个服务级别的自定义方法。
    2. rpc Watch(WatchRequest) returns (WatchResponse) {
    3. // 自定义方法映射到HTTP POST。所有请求参数通过body传递。
    4. option (google.api.http) = {
    5. };
    6. }
    7. // 这是一个资源集合级别的自定义方法。
    8. rpc ClearEvents(ClearEventsRequest) returns (ClearEventsResponse) {
    9. option (google.api.http) = {
    10. post: "/v3/events:clear"
    11. body: "*"
    12. };
    13. }
    14. // 这是一个资源级别的自定义方法。
    15. rpc CancelEvent(CancelEventRequest) returns (CancelEventResponse) {
    16. option (google.api.http) = {
    17. };
    18. }
    19. // 这是批量获取的自定义方法。
    20. rpc BatchGetEvents(BatchGetEventsRequest) returns (BatchGetEventsResponse) {
    21. // 批量获取方法映射到HTTP GET
    22. option (google.api.http) = {
    23. get: "/v3/events:batchGet"
    24. };
    25. }

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

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

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

    • 使用不同的参数查询资源 (使用标准list方法,跟标准list过滤)。
    • 关闭一个通知(使用标准delete方法)。