天天看點

RESTful API設計規範REST簡介使用HTTP的RESTful API的一些主要設計原則參考連接配接

REST簡介

在2000年,羅伊·菲爾德(Roy Fielding)提出了代表性狀态轉移(REST)作為設計Web服務的體系結構方法。REST是一種用于建構基于超媒體的分布式系統的體系結構樣式。REST獨立于任何底層協定,不一定與HTTP綁定。但是,大多數常見的REST實作使用HTTP作為應用程式協定,并且本指南重點介紹為HTTP設計REST API。

使用HTTP的RESTful API的一些主要設計原則

URL設計

避免在URI中使用動詞,應該采用“動詞 + 名詞”的設計結構。這是因為HTTP動詞應足以描述對資源執行的操作。

比如,GET /articles這個指令,GET是動詞,/articles是名詞。可以解釋為:擷取全部或者

使用标準HTTP動詞對資源執行操作有:

  • GET:讀取(Read)
  • POST:建立(Create)
  • PUT:更新(Update)
  • PATCH:更新(Update),通常是部分更新
  • DELETE:删除(Delete)

傳回格式設計

  • 不要傳回純文字,應該使用JSON作為資料格式,注意這裡不是json字元串,而是json對象,是以http header的Content-Type屬性要設為application/json
  • 用戶端請求時,也要明确告訴伺服器,可以接受 JSON 格式,即請求的 HTTP 頭的ACCEPT屬性也要設成application/json

使用複數名詞

既然 URL 是名詞,那麼應該使用複數,還是單數?

這沒有統一的規定。假如現在有兩種場景,擷取文章id為110的資料。那麼我可以這樣設計:

  • GET /article/110 可以了解為擷取文章,id為110的資料
  • GET /articles/110 可以了解為從資料集中(文章集合)中擷取,id為110的資料

    其實這兩種都是可以了解的。但是後者更能展現出從資料集中讀取資料,跟讀取資源的過程更貼切,例如:

SELECT * FROM articles WHERE id = 110;
           

是以為了統一起見,建議都使用複數 URL。

在響應正文中傳回錯誤詳細資訊

當API伺服器處理錯誤時,友善(并建議!)在JSON正文中傳回錯誤詳細資訊,以幫助使用者進行調試。

{
  "error": "Invalid payoad.",
  "detail": {
    "surname": "This field is required."
  }
}
           

發生錯誤時,不要傳回 200 狀态碼

就比如說,HTTP 相應的狀态碼是200,但是伺服器的響應可以是sucess也可能是error:

HTTP/1.1 200 OK
Content-Type: text/html
{
    "status": "failure",
    "data": {
        "error": "Expected at least two items in list."
    }
}
           

*結果,在判斷status狀态之前,我必須檢查狀态碼和臨時字段,以確定一切正常。這種設計是真正的禁忌,因為它破壞了API及其使用者之間的信任。

是以我們應該怎麼做呢?

使用狀态代碼,僅使用響應正文提供錯誤詳細資訊。

HTTP/1.1 400 Bad Request
Content-Type: application/json
{
    "error": "Expected at least two items in list."
}
           

狀态碼

2xx 狀态碼

200狀态碼表示操作成功,但是不同的方法可以傳回更精确的狀态碼。

  • GET: 200 OK
  • POST: 201 Created
  • PUT: 200 OK
  • PATCH: 200 OK
  • DELETE: 204 No Content

    上面代碼中,POST傳回201狀态碼,表示生成了新的資源;DELETE傳回204狀态碼,表示資源已經不存在。

    此外,202 Accepted狀态碼表示伺服器已經收到請求,但還未進行處理,會在未來再處理,通常用于異步操作。

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: /articles/110
           

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:用戶端的請求次數超過限額。

5xx 狀态碼

5xx狀态碼表示服務端錯誤。一般來說,API 不會向使用者透露伺服器的詳細資訊,是以隻要兩個狀态碼就夠了。

  • 500 Internal Server Error:用戶端請求有效,伺服器處理時發生了意外。
  • 503 Service Unavailable:伺服器無法處理請求,一般用于網站維護狀态。

提供連結

這一種目前比較少用。但是可以考慮用。其實就是在擷取資源的時候,直接傳回下一步需要操作的URL。例如:

HTTP/1.1 200 OK
Content-Type: application/json
{
  "status": "In progress",
   "links": {[
    { "rel":"cancel", "method": "delete", "href":"/articles/status/110" } ,
    { "rel":"edit", "method": "put", "href":"/articles/status/12345" }
  ]}
}
           

參考連接配接

RESTful API Design: 13 Best Practices to Make Your Users Happy, by Florimond Manca

https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design