1. 程式人生 > >RESTFul API最佳實踐

RESTFul API最佳實踐

RESTful API最佳實踐

RESTful API 概述

基本概念

REST 英文全稱:Representational State Transfer,直譯為:表現層狀態轉移。首次是由Roy Thomas Fielding在他2000年的博士論文中提出。

REST是一種描述網路中clientserver之間的資源互動方式。

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