RESTFul API最佳實踐
RESTful API最佳實踐
RESTful API 概述
基本概念
REST 英文全稱:Representational State Transfer,直譯為:表現層狀態轉移。首次是由Roy Thomas Fielding在他2000年的博士論文中提出。
REST是一種描述網路中client
和server
之間的資源互動方式。
而RESTful API
就是完全遵循REST
方式的一套API
設計規範,簡單來說,通過API來描述資源的訪問方式:
- 通過
HTTP URL
描述訪問什麼資源 - 通過
HTTP METHOD
描述對資源的互動方式 - 通過
HTTP CODE
描述資源的互動結果
冪等性
冪等性(Idempotence)本身是一個數學概念,在HTTP/1.1規範中冪等性是指
Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.
如果某個方法呼叫一次或多次產生的副作用是相同的,那麼這個方法具有冪等性。
比如在HTTP中使用GET獲取某個資源,無論呼叫多少次,產生的額外效果都是從伺服器獲取資源,所以GET方式具有冪等性。
而POST方法用於在伺服器上建立一個資源,由於最終建立的結果每次都是不同的,所以POST不具有冪等性。
但是PUT方法卻是冪等的,因為每次呼叫產生的效果都是對資源進行更新。
安全方法
安全方法是指不修改資源的 HTTP 方法。譬如,當使用 GET 或者 HEAD 作為資源 URL,都必須不去改變資源的表現形式。
注意:安全方法並不是指伺服器上的資源完全不變,而是指資源的表現形式。
比如GET方法導致資料上報,關聯的一些資料記錄等,他實際上是改變了伺服器上的某些附加資源的,但是這並不會改變資源的表現形式。
HTTP中的安全方法有:
- GET
- HEAD
- PATCH
RESTful API設計規則
HTTP URL
HTTP URL
只用於描述訪問的資源,而不應該包含對資源的互動方式。HTTP URL
Best Practice
:
- 將API部署在專用的域名上
- 不使用任何大寫字元
- 不使用下劃線
_
,可使用中劃線-
代替 - 引數列表要進行編碼
- 不應該出現描述資源互動方式的動詞,應儘量使用描述資源的名詞
URI
中的名詞表示資源集合,應該使用複數形式- 應該避免資源層級太深,可以適當使用引數減少層級
- 使用斜杆
/
表示資源之間的層級關係 - 在
URI
的末尾避免使用/
- 避免在
URI
中使用副檔名 - 如果有必要,需要在
URI
中新增版本號標識
相應的示例如下:
// 下面列出幾個bad case以及修改方法
/userPost // should use uppercase letter
-> /user-posts
/user/post // should use resource plural
-> /users/posts
/users/addPost // avoid using react verb
-> POST /users/posts
/users/posts/ // remove the last `/`
-> /users/posts
/users/posts/picture.gif // remove the extension `.gif`
-> /users/posts/picture
/users/recent_posts // use `-` replace `_`
-> /users/recent-posts
/users/posts?title=up up // param encode
-> /users/posts?name=up%20up
/users/posts/games/picture/today // avoid too deep relations
-> /users/posts/picture?type=game&time=today
/users/learning-posts // add version tag
-> /v1/users/learning-posts
補充說明:
/users/search
像這個URI,雖然包含動詞search
,但是search
並沒有描述對資源的互動方式,所以這種URI也是可以的/users/posts
,/user-posts
這樣的兩個URI,第一個描述了層級關係,第二個沒有,但是兩個URI任然能夠很明確的表示資源,並沒有誰最好的說法,可以結合所在團隊的命名習慣等來選取
HTTP METHOD
嚴格使用下面的HTTP方法來描述資源CURD操作方式,應該記錄避免在POST
方式中刪除資源等違背常規的操作:
GET
: 查詢資源POST
: 建立資源PUT
: 更新資源DELETE
: 刪除資源
對於一些GET
中一次性獲取大量資源的情況下,比如獲取一萬個指定資源的情況,可能會出現HTTP URL
超過長度限制,這個時候可以分批獲取。
雖然新版的HTTP標準支援在GET
請求中傳送body
,但是一些網路伺服器並不能很好的支援,應該慎重使用。
另外對於複雜的資源獲取,應該提供通用的資源篩選、排序、分頁、欄位選擇等功能支援,並統一引數規範。例如:
Filtering:
GET /cars?color=red Returns a list of red cars
GET /cars?seats<=2 Returns a list of cars with a maximum of 2 seats
Sorting:
GET /cars?sort=-manufactorer,+model
Field selection:
GET /cars?fields=manufacturer,model,id,color
Paging:
GET /cars?offset=10&limit=5
覆蓋HTTP方法
一些HTTP客戶端只支援GET和POST請求。為了能夠加強這些客戶端的訪問能力,API需要能夠覆蓋HTTP方法。
儘管這裡沒有任何強制的標準,但流行的做法是API會接收一個請求頭X-HTTP-Method-Override,它的值可以是PUT、PATCH或者DELETE三者之一。
注意,用來覆蓋HTTP方法的header只能在POST請求中被接受。GET請求永遠不能修改伺服器上的資料。
HTTP RESPONSE
關於HTTP請求的返回值,有以下幾點Best Practice
:
- 採用格式化返回資料,推薦
json
- 充分利用HTTP狀態碼來描述錯誤型別
- 規範返回資料的統一格式,以及細分錯誤型別和提示
- 應該儘量返回有用的錯誤資訊和提示,唯一的錯誤碼
常用的HTTP狀態碼:
200
OK - 對成功的GET、PUT、PATCH或DELETE操作進行響應。也可以被用在不建立新資源的POST操作上201
Created - 對建立新資源的POST操作進行響應。應該帶著指向新資源地址的Location header)204
No Content - 對不會返回響應體的成功請求進行響應(比如DELETE請求)304
Not Modified - HTTP快取header生效的時候用400
Bad Request - 請求異常,比如請求中的body無法解析401
Unauthorized - 沒有進行認證或者認證非法。當API通過瀏覽器訪問的時候,可以用來彈出一個認證對話方塊403
Forbidden - 當認證成功,但是認證過的使用者沒有訪問資源的許可權404
Not Found - 當一個不存在的資源被請求405
Method Not Allowed - 所請求的HTTP方法不允許當前認證使用者訪問410
Gone - 表示當前請求的資源不再可用。當呼叫老版本API的時候很有用415
Unsupported Media Type - 如果請求中的內容型別是錯誤的422
Unprocessable Entity - 用來表示校驗錯誤429
Too Many Requests - 由於請求頻次達到上限而被拒絕訪問
參考文件
- https://en.wikipedia.org/wiki/Representational_state_transfer
- https://restfulapi.net/resource-naming/
- https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design
- https://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/
- https://blog.florimond.dev/restful-api-design-13-best-practices-to-make-your-users-happy