RESTful API設計準則

背景

  • 傳統的RPC API設計偏向于傳統的C/S架構,對于B/S模式的WEB應用已經不適用
  • 需要一種全新的結構清晰、符合標準、易于理解、擴展方便的設計準則

RESTful API

  • RESTful API是目前比較成熟的一套互聯網應用程序的API設計理論
  • 符合REST設計理念的WEB API,我們稱之為RESTful API
  • REST的全稱是Representational State Transfer,即表述性狀態(tài)轉移

Representational State Transfer

  • Representational,即Resource的表現層,用于表述資源的一種方式
    • 常用的表述方式有,JSON|XML|HTML|TEXT等
  • Resource,就是網絡上的一個實體,或者說是網絡上的一個具體信息
    • 可以是一個文本|圖片|歌曲|服務,總之就是一個具體的實體
    • 可以用一個URI(統一資源定位符)指向它,每種資源對應一個特定的URI
    • 要獲取這個資源,訪問它的URI就可以,因此URI就成了每一個Resource的地址或獨一無二的識別符
  • State Transfer,即狀態(tài)轉化
    • 訪問一個網站,就代表了客戶端和服務器的一個互動過程,過程中勢必涉及到數據和狀態(tài)的變化
    • 互聯網通信協議HTTP協議,是一個無狀態(tài)協議,這意味著,所有的狀態(tài)都保存在服務器端
  • 因此,如果客戶端想要操作服務器,必須通過某種手段,讓服務器端發(fā)生"狀態(tài)轉化"(State Transfer)。而這種轉化是建立在表現層之上的,所以就是"表現層狀態(tài)轉化"

HTTP操作

狀態(tài)轉化由HTTP操作實現,并不由URI地址表示

操作 HTTP Method URI
獲取列表數據 GET /collection
添加數據 POST /collection
查看數據 GET /collection/{id}
修改全量數據 PUT /collection/{id}
修改部分數據 PATCH /collection/{id}
刪除數據 DELETE /collection/{id}

注:其中collection指資源集合(復數形式),比如users、materials、groups

常見錯誤集:

# 路徑中存在動作詞
POST /insert_material

# 不應用單數,應用集合(復數)
POST /material

# PUT是全量更新,此時會導致所有沒有值的屬性都被置空,而本意是改一個屬性
PUT /materials/{id}
body:{"location":"A1"}

# 網上匯款,從賬戶1向賬戶2匯款500元,動詞不應該在URI中
POST /accounts/1/transfer/500/to/2
# 正確的寫法是將操作服務化
POST /transaction
body:{from:1, to:2, amount:500.00}

HTTP操作延伸

由于RESTful中,只能對單一資源進行,但是實際應用中又有大量的批量場景,因此對RESTful進行擴展,增加一個服務:batch
注:該定義非RESTful準則,僅用于自己項目內部約定,供參考

操作 HTTP Method URI
添加數據 POST /collection/batch
修改全量數據 PUT /collection/batch
修改部分數據 PATCH /collection/batch
刪除數據 DELETE /collection/{id},{id},...

過濾信息(Filtering)

如果記錄數量很多,服務器不可能都將它們返回給用戶。API應該提供參數,過濾返回結果,下面是一些常見的參數:

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

返回結果

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

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

針對批量操作:

  • POST /collection/patch:返回新生成的資源對象列表
  • PUT /collection/patch:返回完整的資源對象列表
  • PATCH /collection/patch:返回完整的資源對象列表
  • DELETE /collection/{id},{id}:返回一個所有資源刪除成功與否的結果列表

狀態(tài)碼(Status Codes)

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

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

狀態(tài)碼的完全列表參見這里

域名

應該盡量將API部署在專用域名之下,如:

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

版本號

應該將API的版本號放入URL,如:

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

參考

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容