歡迎訪問陳同學博客原文
本文記錄了 RESTful API 的一些實踐經驗,內容綜合了部分 後端圈.研習小組 關於 REST 的探討結果,僅簡單帶一下理論知識,更多可參考:
- Roy Thomas Fielding 2000年的 博士論文 中 Chapter 5: Representational State Transfer (REST)
- 阮一峯:理解 RESTful 架構
簡介
REST 是 Representational State Transfer 首字母縮寫,翻譯爲 表現層狀態轉化,加上主語 資源,應爲:資源通過表現層進行狀態轉化。
例如:服務端提供接口查詢單個用戶,返回數據格式可以是:JSON、XML、文本、HTML等,這就是資源的表現形式。客戶端通過HTTP(HTTPS)協議傳遞某種格式(表現層)的數據給服務端來完成對資源的狀態變更。
技術團隊理解並統一遵循 RESTful 接口的規範,可避免雜亂的接口定義,使得接口顧名思義,提高效率。
接口組成
接口由HTTP動詞、域名、版本、Endpoint組成。
GET https://example.com/api/v1/users
Endpoint
Endpoint 在 RESTful 中理解爲資源,使用複數名詞來命名。例如:用戶 users。
版本
表示接口版本號,可直接放入URL。例如:
/v1/users
/v2/users
也有使用自定義 HTTP Header 屬性來表示版本,不過不推薦。
域名
如果使用主域名,可以在域名中加入 /api
前綴,Proxy 可根據該部分進行代理。如果使用專用域名也可以不加。
https://example.com/api 主域名
https://api.example.com API專用域名
HTTP動詞
通過HTTP動詞結合URL來操作資源,下面是常用用法。
HTTP 動詞 | 資源 | 含義 |
---|---|---|
GET | users | 查詢所有用戶 |
GET | users/{id} | 查詢某用戶 |
GET | users/{id}/orders | 查詢某用戶的所有訂單 |
POST | users | 新增用戶 |
PUT | users/{id} | 更新某個用戶信息,需提供用戶改變後的所有信息 |
PATCH | users/{id} | 更新某個用戶信息,只需提供改變的屬性 |
DELETE | users/{id} | 刪除某個用戶 |
接口命名實踐
實際業務中,除普通的CRUD外,會有許多其他場景,下面例舉一些。
操作資源
通常會開放一些專用接口來操作資源,比如:凍結用戶、解凍用戶。
可將對資源的操作抽象爲actions,這樣通過HTTP Method + actions 就可以表示多種操作。
凍結用戶
PATCH /users/1/actions/freeze
解凍用戶
PATCH /users/uniqueCheck
注:團隊內保持同一規範即可,也可不用actions,例如直接用 PATCH /users/1/freeze
批量操作
- 批量查詢
根據用戶ID批量檢索用戶
GET /users/actions/batchQuery?userIds=1,2,3
- 批量更新
根據用戶ID批量失效用戶
PATCH /users/actions/batchFreeze
檢索單個資源
除根據主鍵檢索信息外,經常會根據其他唯一字段來檢索數據。例如利用手機號、郵箱檢索單個用戶:
GET /users/actions/singleQuery?mobile=xxx
GET /users/actions/singleQuery?mail=xxx
唯一性檢查
在業務需要進行唯一性檢查時,需要提供唯一性檢查接口(一個接口可支持多個字段的檢查)
GET /users/actions/uniqueCheck?userName=xxx
獲取鍵值對數據
經常需要提供key,value類型的數據集合,以用戶爲例:
GET /users/kv
可支持參數查詢
GET /users/kv?lastName=張三
GET /users/kv?queryKey=張三
可支持分頁查詢
GET /users/kv?pageNum=1&pageSize=50
數量查詢
查詢男性用戶總數
GET /users/count?sex=1
分頁與排序參數
- 分頁(默認都分頁)
GET /users?pageNum=1&pageSize=10
- 獲取所有數據,不分頁,可通過特定參數來表示不分頁,都使用
/users
接口
GET /users?noPage=1
- 排序1(帶下劃線表示desc,不帶表示默認的asc)
GET /users?sort=userName,_lastName
- 排序2(通過JSON格式字符串傳遞排序信息)
GET /users?sort={"userName":"desc", "lastName":"asc"}
更新資源單個屬性
對於某些屬性,產品設計時可以進行單獨更新。
格式:PATCH /resources/{id}/:attribute?value=xxx
PATCH /users/1/mobile?value=135xxxxxxxx
Action 命名實踐
上面是接口命名的實踐,這裏例舉下Controller中Actions的實踐。
還是以用戶爲例,但未使用 actions
.
操作 | Action Name | URI | HTTP Method |
---|---|---|---|
查詢所有數據 | list | /users | GET |
創建單個資源 | create | /users | POST |
更新單個資源 | update | /users/1 | PUT |
刪除單個資源 | delete | /users/1 | DELETE |
查詢數量 | count | /users/count | GET |
鍵值對數據 | kv | /users/kv | GET |
批量查詢 | batchQuery | /users/batchQuery | GET |
查詢單個資源 | singleQuery | /users/singleQuery | GET |
唯一性檢查 | uniqueCheck | /users/uniqueCheck | POST |
更新資源單個屬性 | updateMobile | /users/1/mobile?value=135xxx | PATCH |
小結
良好且統一的接口命名規範,看上去是 賞心悅目 的,非常舒服。由於RESTful風格接口僅提供了基礎的幾種操作,因此技術團隊需要進行拓展並規範下來。
無論以何種形式命名,能夠使用統一的風格即可,本文僅起一個參考作用。
歡迎關注陳同學的公衆號,一起學習,一起成長