1. 程式人生 > >11. RESTful API 設計最佳實踐

11. RESTful API 設計最佳實踐

API 設計規範

URI 的設計

  1. 在RESTful架構中,每個網址代表一種資源(resource),一般是名詞且表示方式為複數

  2. URI 使用小寫,如果資源由多個單片語成,使用 - 連線。

  3. 對於資源的具體操作型別,由HTTP動詞表示。

    常用的HTTP動詞有下面五個(括號裡是對應的SQL命令)。

    • GET(SELECT):從伺服器取出資源(一項或多項)。

    • POST(CREATE):在伺服器新建一個資源。

    • PUT(UPDATE):在伺服器更新資源。

    • DELETE(DELETE):從伺服器刪除資源。

    下面是一些例子。

    • GET /zoos:列出所有動物園
    • POST /zoos:新建一個動物園
    • GET /zoos/ID:獲取某個指定動物園的資訊
    • PUT /zoos/ID:更新某個指定動物園的資訊
    • DELETE /zoos/ID:刪除某個動物園
    • GET /zoos/ID/animals:列出某個指定動物園的所有動物
    • DELETE /zoos/ID/animals/ID:刪除某個指定動物園的指定動物

過濾、排序和搜尋等資訊

過濾

對每一個欄位使用一個唯一查詢引數,就可以實現過濾。

例如:

GET /tickets?state=open // 獲取狀態為開放的票

排序

採用泛型引數(sort)來描述排序的規則,排序引數採取逗號分隔的欄位列表的形式,每一個欄位前都可能有一個負號來表示按降序排序。

例如:

GET /tickets?sort=-priority // 獲取票據列表,按優先順序欄位降序排序
GET /tickets?sort=-priority,created_at // 獲取票據列表,按“priority”欄位降序排序。在一個特定的優先順序內,較早的票排在前面。

搜尋

當我們需要全文搜尋或者需要搜尋多個欄位時,我們可以採取泛型引數(q)的形式來表示。

GET /tickets?q=return // 查詢印有 "return" 字樣的票

分頁引數

使用 pageper_page 來表示當前處於第幾頁及每頁的記錄數。

GET /tickets?page=1&per_page=10

響應和錯誤處理

響應

統一採用 json 形式。

json 中的欄位名採用 snake_case 形式,如 err_code 而非 errCode

結構和錯誤處理

由於在複雜的系統中 http 狀態碼並不能覆蓋所有的錯誤處理。為此我們採用所有響應的狀態碼都為 200,只是在返回結果中表明狀態和錯誤資訊,結構如下:

{
    "status": "success", // success or fail,  用來表明請求狀態:成功 或 出錯
    "err_code": "",
    "err_msg": "",
    "data": {
        ...
    }
}

// 如果 status 為 success,則可讀取 data 裡面的內容作後續處理。
// 如果 status 為 fail ,則讀取 err_code 和 err_msg。

這樣設計的好處在於既不用關心 http 狀態碼,也不用對成功或失敗來處理不同的JSON結構。

版本控制(delete)

給 API 標識版本有利於向後相容和軟體的平滑升級。

關於 API 的版本是應該包含在 URL 中還是請求頭中的討論,沒有明確的答案,誰都說服不了誰。

此處,我們採取放在 URL 中的方式,比較簡單明瞭。

例如:

https://api.example.com/v1/candidates

認證

由於 Restful API 是無狀態的,當我們需要進行許可權認證時,可在請求頭裡加上請求憑證(access_token),可採用 OAuth 2.0 框架。

快取

HTTP提供了自帶的快取框架。你需要做的是在返回的時候加入一些返回頭資訊,在接受輸入的時候加入輸入驗證。基本兩種方法:

  • ETag:當生成請求的時候,在HTTP頭裡面加入ETag,其中包含請求的校驗和和雜湊值,這個值和在輸入變化的時候也應該變化。如果輸入的HTTP請求包含IF-NONE-MATCH頭以及一個ETag值,那麼API應該返回304 not modified狀態碼,而不是常規的輸出結果。
  • Last-Modified:和etag一樣,只是多了一個時間戳。返回頭裡的Last-Modified:包含了 RFC 1123 時間戳,它和IF-MODIFIED-SINCE一致。HTTP規範裡面有三種date格式,伺服器應該都能處理。

未完待續…

由於 api 規範的定製不是一個一蹴而就的事情,可能會隨著遇到的問題有所增加或調整,後面也會持續的完善和更新。

其他規範可參考

Restful API 最佳實踐

Restful API 設計最佳實踐