1. 協議
API 與用戶的通信協議,總是使用 HTTPs
2. 域名
應該儘量將 API 部署在專用域名下:
https://api.example.com
如果 API 很簡單,不會有進一步擴展,可以考慮放在主域名下:
https://example.com/api/
3. 版本
應該將 API 的版本號放入 URL:
https://api.example.com/v1/
另一種做法是,將版本號放在 HTTP 頭信息中,但不如放在 URL 方便和直觀。(不過如果 API 放在主域名下呢?再加上版本號是否會顯得 API 很冗餘?)
4. 路徑
在 RESTful 架構中,每個網址代表一種資源,所以網址中不能有動詞,只能有名詞,而且所用的名詞往往和數據庫中的表名對應。一般來說,數據庫中的表都是同種記錄的 "集合",所以 API 中的名詞也應該使用複數。
舉例來說,有一個 API 提供動物園(zoo)的信息,還包括各種動物和僱員的信息,則它的路徑應該設計成這樣:
https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees
URI 中需要注意的幾點:
- 不用大寫
- 用中槓 - 不用下槓 _
- 參數列表要 encode
- URI 中名詞表示資源集合,使用複數形式
5. HTTP 動詞
常用的 HTTP 動詞有下面五個(括號裏對應的 SQL 命令):
GET(SELECT):從服務器取出資源(一項或多項)
POST(CREATE):從服務器新建一個資源
PUT(UPDATE):在服務器更新資源(客戶端提供改變後的完整屬性)
PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性)
DELETE(DELETE):從服務器刪除資源
下面是一些例子:
POST /zoos:新建一個動物園
GET /zoos/ID:獲取某個指定動物園的信息
PUT /zoos/ID:更新某個指定動物園的信息(提供該動物園的全部信息)
PATCH /zoos/ID:更新某個指定動物園的信息(提供該動物園的部分信息)
DELETE /zoos/ID:刪除某個動物園
GET /zoos/ID/animals:列出某個指定動物園的所有動物
DELETE /zoos/ID/animals/ID:刪除某個指定動物園的指定動物
RESTful 架構風格具有 統一接口 的特點,即使用不同的 http 方法表達不同的行爲,不再出現類似 /zoos/add,/zoos/ID/delete 這樣的形式。
在 RESTful 的標準中,PUT 和 PATCH 都可以用於修改操作,它們的區別是 PUT 需要提交整個對象,而 PATCH 只需要提交修改的信息。但是在我看來實際應用中不需要這麼麻煩,所以我一律使用 PUT,並且只提交修改的信息。
6. 過濾信息
如果記錄數量很多,服務器不可能將它們全部返回。API 應該提供參數,過濾返回結果:
?limit=10
?offset=10
?page=2&per_page=100
?sortby=name&order=asc
?animal_type_id=1
參數的設計允許存在冗餘,即允許 API 路徑和 URL 參數偶爾有重複。比如 GET /zoos/ID/animals 和 GET /animals?zoo_id=ID 的含義是相同的
7. 狀態碼
200 OK - [GET]:服務器成功返回請求的數據
201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功
204 NO CONTENT - [DELETE]:用戶刪除數據成功
400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改的操作
404 NOT FOUND - [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操作
500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤,用戶無法判斷髮出的請求是否成功(該狀態碼是服務器自動生成返回的,不能手動將狀態碼返回 500)
有很多服務器將返回狀態碼一直設爲 200,然後在返回 body 裏面自定義一些狀態碼來表示服務器返回結果的狀態碼。由於 RESTful 是直接使用的 HTTP 協議,所以它的狀態碼也要儘量使用 HTTP協議的狀態碼。
8. 錯誤處理
如果狀態碼是 4xx,就應該向用戶返回出錯信息。
{
error: "Invalid API key"
}
9. 返回結果
針對不同操作,服務器向用戶返回的結果應該符合以下規範。
GET /collection:返回資源對象的列表(數組)
GET /collection/resource:返回單個資源對象
POST /collection:返回新生成的資源對象
PUT /collection/resource:返回完整的資源對象
PATCH /collection/resource:返回完整的資源對象
DELETE /collection/resource:返回一個空文檔