RESTful API 設計指南

jopen 10年前發布 | 22K 次閱讀 RESTful

    作者: 阮一峰

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

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

        今天,我將介紹 RESTful API 的設計細節,探討如何設計一套合理、好用的 API。我的主要參考資料是這篇《Principles of good RESTful API Design》

RESTful API 設計指南

        一、協議

        API 與用戶的通信協議,總是使用 HTTPs 協議

        二、域名

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

https://api.example.com

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

https://example.org/api/

        三、版本(Versioning)

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

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

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

        四、路徑(Endpoint)

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

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

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

https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees

        五、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:指定返回記錄的開始位置。
?sortby=name&order=asc:指定返回結果按照哪個屬性排序,以及排序順序。
?animal typeid=1:指定篩選條件

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

        七、狀態碼(Status Codes)

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

200 OK - [GET]:服務器成功返回用戶請求的數據,該操作是冪等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功。
204 NO CONTENT - [DELETE]:用戶刪除數據成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操作,該操作是冪等的。。
404 NOT FOUND - [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操作,該操作是冪等的。
500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤,用戶將無法判斷發出的請求是否成功。

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

        八、返回結果

        針對不同操作,服務器向用戶返回的結果應該符合以下規范。

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 https://www.example.com/zoos",
  "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。

        (完)

                    <span id="shareA4" class="fl">                            
                        </span>
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!