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方法特性概覽
HTTP Method | 冪等性 | 安全性 |
---|---|---|
OPTIONS | yes | yes |
GET | yes | yes |
HEAD | yes | yes |
PUT | yes | no |
POST | no | no |
DELETE | yes | no |
PATCH | no | no |
RESTful API設計規則
HTTP URL
HTTP URL
只用於描述訪問的資源,而不應該包含對資源的交互方式。HTTP URL
的Best Practice
:
- 將API部署在專用的域名上,如
api.example.com
- 不使用任何大寫字符
- 不使用下划線
_
,可使用中划線-
代替來分割單詞 - 參數列表要進行URL編碼
- 不應該出現描述資源交互方式的動詞,應盡量使用描述資源的名詞
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