RESTful介面設計
- 2020 年 3 月 5 日
- 筆記
RESTful API
RESTful是一種API的設計規範,用於Web數據介面的設計
REST,表示性狀態轉移(representation state transfer)。簡單來說,就是用URI表示資源,用HTTP方法(GET, POST, PUT, DELETE)表徵對這些資源的操作。
Resource: 資源,即數據,存在互聯網上的可被訪問的實體
Representation: 數據的某種表現形式,如HTML, JSON。
State Transfer:狀態變化,HTTP方法實現
編寫RESTful介面可以參照以下原則
一、URL的設計
如果可能,資源URI應基於名詞(資源)而不是動詞(對資源的操作)。
RESTful 的核心思想是客戶端發出的數據操作指令都是"動詞 + 賓語"的結構。比如,GET /articles這個命令,GET是動詞,/articles是賓語。而不寫成/getArticls,Get這個動作可以通過http的請求方法體現
如上圖所示,同一個URL,因為http請求的方法不同在API設計時有多種含義
避免多級的URL
錯誤示例: GET /articles/published GET /authors/12/categories/2
這種 URL 不利於擴展,語義也不明確,往往要想一會,才能明白含義。
可以除了第一級外,其他級別用查詢字元串表達
GET /authors/?id=12categories=2 GET /articles?published=true
二、狀態碼
HTTP狀態碼是伺服器給客戶端響應狀態欄位的描述。
HTTP狀態碼可以分為5類
1xx:相關資訊 2xx:操作成功 3xx:重定向 4xx:客戶端錯誤 5xx:伺服器錯誤
對於業務流程的設計常用的狀態碼是2xx
200狀態碼錶示操作成功,但是不同的方法可以返回更精確的狀態碼。
GET: 200 OK POST: 201 Created PUT: 200 OK PATCH: 200 OK DELETE: 204 No Content
上面程式碼中,POST返回201狀態碼,表示生成了新的資源;DELETE返回204狀態碼,表示資源已經不存在。
202 Accepted狀態碼錶示伺服器已經收到請求,但還未進行處理,會在未來再處理。
2.3 3xx 狀態碼
API 用不到301狀態碼(永久重定向)和302狀態碼(暫時重定向,307也是這個含義),因為它們可以由應用級別返回,瀏覽器會直接跳轉,API 級別可以不考慮這兩種情況。
API 用到的3xx狀態碼,主要是303 See Other,表示參考另一個 URL。它與302和307的含義一樣,也是"暫時重定向",區別在於302和307用於GET請求,而303用於POST、PUT和DELETE請求。收到303以後,瀏覽器不會自動跳轉,而會讓用戶自己決定下一步怎麼辦。下面是一個例子。
HTTP/1.1 303 See Other Location: /api/orders/12345
2.4 4xx 狀態碼
4xx狀態碼錶示客戶端錯誤,主要有下面幾種。
400 Bad Request:伺服器不理解客戶端的請求,未做任何處理。 401 Unauthorized:用戶未提供身份驗證憑據,或者沒有通過身份驗證。 403 Forbidden:用戶通過了身份驗證,但是不具有訪問資源所需的許可權。 404 Not Found:所請求的資源不存在,或不可用。 405 Method Not Allowed:用戶已經通過身份驗證,但是所用的 HTTP 方法不在他的許可權之內。 410 Gone:所請求的資源已從這個地址轉移,不再可用。 415 Unsupported Media Type:客戶端要求的返回格式不支援。比如,API 只能返回 JSON 格式,但是客戶端要求返回 XML 格式。 422 Unprocessable Entity :客戶端上傳的附件無法處理,導致請求失敗。 429 Too Many Requests:客戶端的請求次數超過限額。
2.5 5xx 狀態碼
5xx狀態碼錶示服務端錯誤。一般來說,API 不會向用戶透露伺服器的詳細資訊,所以只要兩個狀態碼就夠了。
500 Internal Server Error:客戶端請求有效,伺服器處理時發生了意外。 503 Service Unavailable:伺服器無法處理請求,一般用於網站維護狀態。
三:伺服器的回應
API 返回的數據格式,不應該是純文本,而應該是一個 JSON 對象,因為這樣才能返回標準的結構化數據。所以,伺服器回應的 HTTP 頭的Content-Type屬性要設為application/json。
客戶端請求時,也要明確告訴伺服器,可以接受 JSON 格式,即請求的 HTTP 頭的ACCEPT屬性也要設成application/json。下面是一個例子。
參考部落格:http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html