RESTful API 設計指南

RESTful API 設計指南

資源介紹參數
資源類別: Java
如遇問題: 聯繫客服/留言反饋
釋放雙眼,帶上耳機,聽聽看~!

原文鏈接:http://www.ruanyifeng.com/blog/2014/05/restful_api.html
來源:阮一峰的網路日誌

由於最近在寫畢業設計的後端,是完全前後分離的項目,所以需要嚴謹的設計API,看到了阮一峰有很不錯的文章,並且開放了轉載,所以記錄學習一下。


網路應用程式,分為前端後端兩個部分。當前的發展趨勢,就是前端設備層出不窮(手機、平板、桌面電腦、其他專用設備……)。

因此,必須有一種統一的機制,方便不同的前端設備與後端進行通訊。這導致 API 構架的流行,甚至出現"API First"的設計思想。RESTful API是目前比較成熟的一套互聯網應用程式的 API 設計理論。我以前寫過一篇《理解 RESTful 架構》,探討如何理解這個概念。

今天,我將介紹 RESTful API 的設計細節,探討如何設計一套合理、好用的 API。我的主要參考了兩篇文章(1,2)。

RESTful API 設計指南

一、協議

API 與使用者的通訊協議,總是使用HTTPs 協議

二、網域

應該盡量將 API 部署在專用網域之下。


如果確定 API 很簡單,不會有進一步擴展,可以考慮放在主網域下。


三、版本(Versioning)

應該將 API 的版本號放入 URL。


另一種做法是,將版本號放在 HTTP 頭信息中,但不如放入 URL 方便和直觀。Github採用這種做法。

四、路徑(Endpoint)

路徑又稱"終點"(endpoint),表示 API 的具體網址。

RESTful 架構中,每個網址代表一種資源(resource),所以網址中不能有動詞,只能有名詞,而且所用的名詞往往與數據庫的表格名對應。一般來說,數據庫中的表都是同種記錄的"集合"(collection),所以 API 中的名詞也應該使用複數。

舉例來說,有一個 API 提供動物園(zoo)的信息,還包括各種動物和僱員的信息,則它的路徑應該設計成下面這樣。




五、HTTP 動詞

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

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

GET(SELECT):從伺服器取出資源(一項或多項)。
POST(CREATE):在伺服器新建一個資源。
PUT(UPDATE):在伺服器更新資源(客戶端提供改變後的完整資源)。
PATCH(UPDATE):在伺服器更新資源(客戶端提供改變的屬性)。
DELETE(DELETE):從伺服器刪除資源。

還有兩個不常用的 HTTP 動詞。

HEAD:獲取資源的元數據。
OPTIONS:獲取信息,關於資源的哪些屬性是客戶端可以改變的。

下面是一些例子。

GET /zoos:列出所有動物園
POST /zoos:新建一個動物園
GET /zoos/ID:獲取某個指定動物園的信息
PUT /zoos/ID:更新某個指定動物園的信息(提供該動物園的全部信息)
PATCH /zoos/ID:更新某個指定動物園的信息(提供該動物園的部分信息)
DELETE /zoos/ID:刪除某個動物園
GET /zoos/ID/animals:列出某個指定動物園的所有動物
DELETE /zoos/ID/animals/ID:刪除某個指定動物園的指定動物

六、篩選信息(Filtering)

如果記錄數量很多,伺服器不可能都將它們返回給使用者。API 應該提供參數,篩選返回結果。

下面是一些常見的參數。

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

參數的設計允許存在冗餘,即允許 API 路徑和 URL 參數偶爾有重複。比如,GET /zoo/ID/animals 與 GET /animals?zoo_id=ID 的含義是相同的。

七、狀態碼(Status Codes)

伺服器向使用者返回的狀態碼和提示信息,常見的有以下一些(方括號中是該狀態碼對應的 HTTP 動詞)。

200 OK - [GET]:伺服器成功返回使用者請求的數據,該操作是冪等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:使用者新建或修改數據成功。
202 Accepted - [*]:表示一個請求已經進入後台排隊(異步任務)
204 NO CONTENT - [DELETE]:使用者刪除數據成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:使用者發出的請求有錯誤,伺服器沒有進行新建或修改數據的操作,該操作是冪等的。
401 Unauthorized - [*]:表示使用者沒有權限(令牌、使用者名、密碼錯誤)。
403 Forbidden - [*] 表示使用者得到授權(與 401 錯誤相對),但是訪問是被禁止的。
404 NOT FOUND - [*]:使用者發出的請求針對的是不存在的記錄,伺服器沒有進行操作,該操作是冪等的。
406 Not Acceptable - [GET]:使用者請求的格式不可得(比如使用者請求 JSON 格式,但是只有 XML 格式)。
410 Gone -[GET]:使用者請求的資源被永久刪除,且不會再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 當創建一個對象時,發生一個驗證錯誤。
500 INTERNAL SERVER ERROR - [*]:伺服器發生錯誤,使用者將無法判斷發出的請求是否成功。

狀態碼的完全列表參見這裡

八、錯誤處理(Error handling)

如果狀態碼是 4xx,就應該向使用者返回出錯信息。一般來說,返回的信息中將 error 作為鍵名,出錯信息作為鍵值即可。

{
    error: "Invalid API key"
}

九、返回結果

針對不同操作,伺服器向使用者返回的結果應該符合以下規範。

GET /collection:返回資源對象的列表(陣列)
GET /collection/resource:返回單個資源對象
POST /collection:返回新生成的資源對象
PUT /collection/resource:返回完整的資源對象
PATCH /collection/resource:返回完整的資源對象
DELETE /collection/resource:返回一個空文檔

十、Hypermedia API

RESTful API 最好做到 Hypermedia,即返回結果中提供鏈接,連向其他 API 方法,使得使用者不查文檔,也知道下一步應該做什麼。

比如,當使用者向 api.example.com 的根目錄發出請求,會得到這樣一個文檔。

{"link": {
  "rel":   "collection ",
  "href":  "https://api.example.com/zoos",
  "title": "List of zoos",
  "type":  "application/vnd.yourformat+json"
}}

上面代碼表示,文檔中有一個 link 屬性,使用者讀取這個屬性就知道下一步該調用什麼 API 了。rel 表示這個 API 與當前網址的關係(collection 關係,並給出該 collection 的網址),href 表示 API 的路徑,title 表示 API 的標題,type 表示返回類型。

Hypermedia API 的設計被稱為HATEOAS。Github 的 API 就是這種設計,訪問api.github.com會得到一個所有可用 API 的網址列表。

{
  "current_user_url": "https://api.github.com/user",
  "authorizations_url": "https://api.github.com/authorizations",
  // ...
}

從上面可以看到,如果想獲取當前使用者的信息,應該去訪問api.github.com/user,然後就得到了下面結果。

{
  "message": "Requires authentication",
  "documentation_url": "https://developer.github.com/v3"
}

上面代碼表示,伺服器給出了提示信息,以及文檔的網址。

十一、其他

(1)API 的身份認證應該使用OAuth 2.0框架。

(2)伺服器返回的數據格式,應該盡量使用 JSON,避免使用 XML。

(完)

聲明:本文為原創作品,版權歸作者所有。未經許可,不得轉載或用於任何商業用途。如若本站內容侵犯了原著者的合法權益,可聯繫我們進行處理。

給TA打賞
共{{data.count}}人
人已打賞
0 條回復 A文章作者 M管理員
    暫無討論,說說你的看法吧