此篇文章討論如何在 API 設計中使用自定義方法。node
自定義方法指五個標準方法以外的 API 方法。應該(should) 只有當標準方法不能完成須要的功能時才使用自定義方法。通常狀況下,API 設計者 應該(should) 在可行的狀況下選擇標準方法。標準方法有更簡潔和明肯定義的語義而且被大多數開發者熟知,因此它們更易於使用而且不易出錯。另外一個優點是 API 平臺對標準方法的支持更好,好比計費、錯誤處理、日誌和監控。api
自定義方法能夠被關聯到資源、集合或服務。它 能夠(may) 接收任意請求並返回任意響應,而且也能夠支持流式請求與響應。ide
自定義方法 應該(should) 使用以下的通用映射方法:post
https://service.name/v1/some/resource/name:customVerb
使用 :
代替 /
來分隔資源名與自定義動詞是爲了支持任意 path 參數,例如,取消刪除(undelete)文件能映射爲 POST /files/a/long/file/name:undelete
。ui
選擇 HTTP 映射時 必須(shall) 遵照以下指南:google
自定義方法 應該(should) 使用 HTTP POST
動詞,由於 POST 有更加靈活的語義翻譯
自定義方法 不該該(should not) 使用 HTTP PATCH
,但 能夠(may) 使用其它 HTTP 動詞。這種狀況下,方法必須(must) 遵循該動詞的標準 HTTP 語義設計
注意,使用 HTTP GET
的自定義方法 必須(must) 是冪等的而且不能有反作用。例如,在資源上實現特殊查詢的自定義方法應該使用 HTTP GET
。日誌
自定義方法中待操做的資源或集合名 應該(should) 映射到 URL path 參數
URL path 必須(must) 以冒號加上自定義動詞作爲後綴
若是自定義方法使用的 HTTP 動詞容許 HTTP 請求體(POST
、PUT
、PATCH
或自定義的 HTTP 動詞),這些自定義方法的 HTTP 配置 必須(must) 使用 body: "*"
而且全部剩餘的請求信息 必須(shall) 映射到 HTTP 請求體中
若是自定義方法使用的 HTTP 動詞不容許 HTTP 請求體(GET
、DELETE
),這些方法的 HTTP 配置 必定不要(must not) 使用 body
,全部剩餘的請求信息 必須(shall) 映射到 HTTP query 參數中
警告:若是服務實現多個 API,必須(must) 當心地建立服務配置以免 API 間的自定義動詞衝突。
// 服務級別的自定義方法 rpc Watch(WatchRequest) returns (WatchResponse) { // 自定義方法映射到 HTTP POST,全部參數放到請求體中 option (google.api.http) = { post: "/v1:watch" body: "*" }; } // 集合級別的自定義方法 rpc ClearEvents(ClearEventsRequest) returns (ClearEventsResponse) { option (google.api.http) = { post: "/v3/events:clear" body: "*" }; } // 資源級別的自定義方法 rpc CancelEvent(CancelEventRequest) returns (CancelEventResponse) { option (google.api.http) = { post: "/v3/{name=events/*}:cancel" body: "*" }; } // 用於批量 get 的自定義方法 rpc BatchGetEvents(BatchGetEventsRequest) returns (BatchGetEventsResponse) { // 批量 get 方法映射到 HTTP GET option (google.api.http) = { get: "/v3/events:batchGet" }; }
一些可選擇自定義方法的其餘狀況:
重啓虛擬機 設計的備選方案能夠是「在重啓資源集合中建立一個重啓資源」(過於複雜)或者「虛擬機具備可變的狀態,客戶端可以將其從運行中改變爲重啓中」(會引入更多問題,好比是否有其餘狀態間的轉變)。此外,重啓是一個被熟知的概念,可以很好地轉換爲知足開發者需求的自定義方法
發送郵件 建立郵件信息並不必定要將它發送出去(草稿)。相對於備選方案(將消息移動到 Outbox 集合),自定義方法的優勢是能夠被 API 用戶更多地發現而且更直接地理解它的概念
員工晉級 若是使用標準的 update
來實現,客戶端必須重複進行管理流程的策略來保證正確的晉級
一些標準方法比自定義方法更好的例子:
使用不一樣的參數查詢資源(使用標準的 list
方法和過濾)
簡單的資源修改(使用帶有字段掩碼的標準 update
方法)
撤消通知(使用標準的 delete
方法)
經常使用的自定義方法名稱列表以下。 API 設計者在引入自已的名稱以前應該考慮這些名稱,以便於跨 API 的一致性
| 方法名 | 自定義動詞 | HTTP 動詞 | 備註 |
| - | - | - | - |
| Canecl | :cancel | POST | 取消未完成的操做(構建、計算等) |
| BatchGet<複數名詞> | :batchGet | POST | 批量取得多個資源(詳情請查看 List 的描述) |
| Move | :move | GET | 將資源從一個父資源移動到另外一箇中 |
| Search | :search | GET | 用於獲取不符合 List 語義的數據 |
| Undelete | :undelete | POST | 恢復之前刪除的資源,推薦的保留期爲30天 |