1. 程式人生 > >Restful API 設計參考原則

Restful API 設計參考原則

width 包裝 修改 api開發 司機 word 屬性 add 數據返回

在項目中,需要為後臺服務撰寫API。剛開始接觸的時候,並沒有考慮太多,就想提供URL,服務端通過該URL進行查詢、創建、更新等操作即可。但再對相關規範進行了解後,才發現,API的設計並沒有那麽簡單,遠遠不是URL的問題,而是一個通信協議的整體架構

1. 使用GET、POST、PUT、DELETE這幾種請求模式

請求模式也可以說是動作、數據傳輸方式,通常我們在web中的form有GET、POST兩種,而在HTTP中,存在下發這幾種。

GET (選擇):從服務器上獲取一個具體的資源或者一個資源列表。
POST (創建): 在服務器上創建一個新的資源。
PUT(更新):以整體的方式更新服務器上的一個資源。

PATCH (更新):只更新服務器上一個資源的一個屬性。
DELETE(刪除):刪除服務器上的一個資源。

2.使用名詞而不是動詞

Resource
資源

GET
POST
創建
PUT
修改
DELETE
/cars 返回 cars集合 創建新的資源 批量更新cars 刪除所有cars
/cars/711 返回特定的car 該方法不允許(405) 更新一個指定的資源 擅長指定資源

不要使用:

/getAllCars
/createNewCar
/deleteAllRedCars

3.Get方法和查詢參數不應該涉及狀態改變

使用PUT, POSTDELETE 方法 而不是 GET 方法來改變狀態,不要使用GET 進行狀態改變:

GET /users/711?activate
GET /users/711/activate

4.使用復數名詞

不要混淆名詞單數和復數,為了保持簡單,只對所有資源使用復數。

/cars 而不是 /car
/users 而不是 /user
/products 而不是 /product
/settings 而部署 /setting

5. 使用子資源表達關系

如果一個資源與另外一個資源有關系,使用子資源:

GET /cars/711/drivers/ 返回 car 711的所有司機

GET /cars/711/drivers/4 返回 car 711的4號司機

6.為集合提供過濾 排序 選擇和分頁等功能

比如在數據過多, 需要對數據進行分頁請求的時候, 我們應該統一 API 請求參數. 常見的有這些.

  • limit=10 指定返回記錄的數量
  • offset=10 指定返回記錄的開始位置。
  • page=2&per_page=100 指定第幾頁,以及每頁的記錄數。
  • sortby=name&order=asc 指定返回結果按照哪個屬性排序,以及排序順序。
  • animal_type_id=1 指定篩選條件

Filtering過濾:

使用唯一的查詢參數進行過濾:

GET /cars?color=red 返回紅色的cars
GET /cars?seats<=2 返回小於兩座位的cars集合

Sorting排序:

允許針對多個字段排序

GET /cars?sort=-manufactorer,+model

這是返回根據生產者降序和模型升序排列的car集合

Field selection

移動端能夠顯示其中一些字段,它們其實不需要一個資源的所有字段,給API消費者一個選擇字段的能力,這會降低網絡流量,提高API可用性。

GET /cars?fields=manufacturer,model,id,color

Paging分頁

使用 limit 和offset.實現分頁,缺省limit=20 和offset=0;

GET /cars?offset=10&limit=5

為了將總數發給客戶端,使用訂制的HTTP頭: X-Total-Count.

鏈接到下一頁或上一頁可以在HTTP頭的link規定,遵循Link規定:

Link: <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=15&limit=5>; rel="next",
<https://blog.mwaysolutions.com/sample/api/v1/cars?offset=50&limit=3>; rel="last",
<https://blog.mwaysolutions.com/sample/api/v1/cars?offset=0&limit=5>; rel="first",
<https://blog.mwaysolutions.com/sample/api/v1/cars?offset=5&limit=5>; rel="prev",

7.版本化你的API

API的開發直接關系了APP是否可以正常使用,如果原本運行正常的API,突然改動,那麽之前使用這個API的APP可能無法正常運行。APP是不可能強迫用戶主動升級的,因此,通過API版本來解決這個問題。也就是說,API的多個版本是同時運行的,而且都要保證可以正常使用。

按照RESTful的規範,不同的版本也應該用相同的API URL,通過header信息來判斷版本,再調用不同版本的程序進行處理。但是這明顯會給開發帶來巨大的成本。使得API版本變得強制性,不要發布無版本的API,使用簡單數字,避免小數點如2.5.

解決辦法有以下幾種:

1.新版本兼容舊版本,所有舊版本的動作、字段、操作,都在新版本中可以被實現,但明顯這樣的維護成本很大;
2.不同的版本,用不同的URL來提供服務,在URL中通過v1、v2來區分版本號,比如v2.api.xxx.com/user的方式,或者http://api.domain.com/v2 或者http://www.domain.com/api/v2 。
3.每個接口有各自的版本,一般為接口添加個version的參數。

8.json數據類型

  • Number:整數或浮點數
  • String:字符串
  • Boolean:true 或 false
  • Array:數組包含在方括號[]中
  • Object:對象包含在大括號{}中
  • Null:空類型

所以,傳輸的數據類型不能超過這六種數據類型。以前,我們曾經試過傳輸Date類型,它會轉為類似於"2016年1月7日 09時17分42秒 GMT+08:00"這樣的字符串,這在轉換時會產生問題,不同的解析庫解析方式可能不同,有的可能會轉亂,有的可能直接異常了。要避免出錯,必須做特殊處理,自己手動去做解析。為了根除這種問題,最好的解決方案是用毫秒數或者字符串表示日期。

返回的數據結構

{
    code:0,
    message: "success",
    data: { key1: value1, key2: value2, ... }
}
  • code: 返回碼,0表示成功,非0表示各種不同的錯誤
  • message: 描述信息,成功時為"success",錯誤時則是錯誤信息
  • data: 成功時返回的數據,類型為對象或數組

data字段只在請求成功時才會有數據返回的。數據類型限定為對象或數組,當請求需要的數據為單個對象時則傳回對象,當請求需要的數據是列表時,則為某個對象的數組。這裏需要註意的就是,不要將data傳入字符串或數字,即使請求需要的數據只有一個,比如token,那返回的data應該為:

// 正確 data: { token: abcdedf } // 錯誤 data: abcdefg

9. 使用Http狀態碼處理錯誤

不同錯誤需要定義不同的返回碼,屬於客戶端的錯誤和服務端的錯誤也要區分,比如1XX表示客戶端的錯誤,2XX表示服務端的錯誤

如果你的API沒有錯誤處理是很難的,只是返回500和出錯堆棧不一定有用

Http狀態碼提供70個出錯,我們只要使用10個左右:

200 – OK – 一切正常
201 – OK – 新的資源已經成功創建
204 – OK – 資源已經成功擅長

304 – Not Modified – 客戶端使用緩存數據

400 – Bad Request – 請求無效,需要附加細節解釋如 "JSON無效"
401 – Unauthorized – 請求需要用戶驗證
403 – Forbidden – 服務器已經理解了請求,但是拒絕服務或這種請求的訪問是不允許的。
404 – Not found – 沒有發現該資源
422 – Unprocessable Entity – 只有服務器不能處理實體時使用,比如圖像不能被格式化,或者重要字段丟失。

500 – Internal Server Error – API開發者應該避免這種錯誤。

使用詳細的錯誤包裝錯誤:

{

"errors": [

{

"userMessage": "Sorry, the requested resource does not exist",

"internalMessage": "No car found in the database",

"code": 34,

"more info": "http://dev.mwaysolutions.com/blog/api/v1/errors/12345"

}

]

}

10.允許覆蓋http方法

一些代理只支持POSTGET方法, 為了使用這些有限方法支持RESTful API,需要一種辦法覆蓋http原來的方法。

使用訂制的HTTP頭 X-HTTP-Method-Override 來覆蓋POST 方法.

Restful API 設計參考原則