你真的瞭解restful api嗎?

前言

在之前,一個網站的完成老是「all in one」,頁面,數據,渲染所有在服務端完成,這樣作的最大的弊端是後期維護,擴展極其痛苦,開發人員必須同時具有先後端知識。因而慢慢的後來興起了先後端分離的思想: 後端負責數據編造,而前端則負責數據渲染,前端靜態頁面調用指定api獲取到有固定格式的數據,再將數據展現出來,這樣呈現給用戶的就是一個」動態「的過程,而關於api這部分的設計則成了一個問題。如何設計出一個便於理解,容易使用的api則成了一個問題。 而所謂的restful就是用來規範咱們的api的一種約束。前端

介紹

restREpresentational State Transfer三個單詞的縮寫,由Roy Fielding於2000年論文中提出,它表明着分佈式服務的架構風格。而若是想你的api被稱爲restful api,只要遵循其規定的約束便可。數據庫

rest設計原則

  1. 客戶端-服務器:經過將用戶UI與數據存儲分開,咱們能夠簡化服務器組件來提升跨多個平臺的用戶界面的可移植性並提升可伸縮性。 它能夠比表現成先後端分離的思想。
  2. 無狀態:從客戶端到服務器的每一個請求都必須包含理解請求所需的全部信息,而且不能利用服務器上任何存儲的上下文。 這表示你應該儘量的避免使用session,由客戶端本身標識會話狀態。(token)
  3. 規範接口:REST接口約束定義:資源識別; 請求動做; 響應信息; 它表示經過uri標出你要操做的資源,經過請求動做(http method)標識要執行的操做,經過返回的狀態碼來表示此次請求的執行結果。
  4. 可緩存: 緩存約束要求將對請求的響應中的數據隱式或顯式標記爲可緩存或不可緩存。若是響應是可緩存的,則客戶端緩存有權重用該響應數據以用於之後的等效請求。 它表示get請求響應頭中應該表示有是否可緩存的頭(Cache-Control) 其中1,2,3約束最爲重要,其中1容易理解。接下來咱們就談談無狀態和規範接口的原則。

uri規範

資源的描述構成了uri,它通常有如下約束:json

  1. 使用名詞。如 user, student, class

api.example.com/class-manag…後端

api.example.com/device-mana…api

api.example.com/user-manage…瀏覽器

api.example.com/user-manage…緩存

  1. 使用http method來對應不一樣的請求動做(數據庫或者業務邏輯) GET:查詢操做:

HTTP GET /devices?startIndex=0&size=20 表示按照查詢條件獲取設備列表服務器

HTTP GET /configurations?startIndex=0&size=20restful

HTTP GET /devices/{id}/configurationssession

HTTP GET /devices/{id}

POST:新增操做:

HTTP POST /device 表示新增一個設備 PUT 更新操做(表明更新一個實體的全部屬性)

HTTP PUT /devices/{id} 表示更新一個設備(設備惟一id區分) PATCH 部分更新(表明更新一個實體的部分屬性)因爲有的瀏覽器兼容性問題,通常推薦使用put

HTTP PATCH /devices/{id} 表示更新device的部分屬性

DELETE 刪除操做 HTTP DELETE /devices/{id} 表示刪除一個設備,根據id區分

  1. 使用連字符( - )而不是(_)來提升URI的可讀性

api.example.com/inventory-m… //更易讀

api.example.com/inventory_m… //更容易出錯

  1. 在URI中使用小寫字母(特殊狀況除外,例如專有名詞) api.example.org/my-folder/m…

  2. 不要使用文件擴展名 文件擴展名看起來很糟糕,不會增長任何優點。刪除它們也會減小URI的長度。沒理由保留它們

    api.example.com/device-mana… / 不要使用它 /

    api.example.com/device-mana… / *這是正確的URI * /

  3. 使用查詢組件過濾URI集合

不少時候,咱們會遇到須要根據某些特定資源屬性對須要排序,過濾或限制的資源集合的要求。爲此,請不要建立新的API - 而是在資源集合API中啓用排序,過濾和分頁功能,並將輸入參數做爲查詢參數傳遞。例如

http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices?region=USA
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ&sort=installation-date
複製代碼
  1. 不要在末尾使用/

做爲URI路徑中的最後一個字符,正斜槓(/)不會添加語義值,並可能致使混淆。最好徹底放棄它們。

  1. 使用http狀態碼定義api執行結果

1xx:信息 通訊傳輸協議級信息。

2xx:成功 表示客戶端的請求已成功接受。

3xx:重定向 表示客戶端必須執行一些其餘操做才能完成其請求。

4xx:客戶端錯誤 此類錯誤狀態代碼指向客戶端。

5xx:服務器錯誤 服務器負責這些錯誤狀態代碼。 另外完整的更爲詳細的狀態碼此處不作贅述。通常簡化版本的api會使用200,400,500,其中400表明客戶端調用有誤,將具體業務邏輯錯誤信息放入response body:

{
  "error": "username.or.password.error"
}
複製代碼
  1. api版本定義

    當咱們須要對現有的api接口升級的時候,由於該api接口已經投入使用,因此新添加的業務可能沒法保證兼容原來的邏輯,這個時候就須要新的接口,而這個接口通常表示對原來的接口的升級(不一樣版本),那版本怎麼定義呢?

  • URI版本控制(推薦) api.example.com/v1 apiv1.example.com
  • 使用自定義請求標頭進行版本控制 Accept-version:v1 Accept-version:v2
  • 使用Accept header 進行版本控制 Accept:application / vnd.example.v1 + json Accept:application / vnd.example + json; version = 1.0

無狀態

使REST API無狀態有一些很是顯着的優勢:

  1. 無狀態經過將API部署到多個服務器,有助於將API擴展到數百萬併發用戶。任何服務器均可以處理任何請求,由於沒有與會話相關的依賴。(集羣)

  2. 無狀態使得REST API不那麼複雜 - 能夠刪除全部服務器端狀態同步邏輯。(刪除session,清理多餘空間)

  3. 無狀態API也很容易緩存。特定軟件能夠經過查看該一個請求來決定是否緩存HTTP請求的結果。從先前的請求中得到的狀態可能會影響這個請求的可緩存性,這並不存在任何不肯定性。它提升了應用程序的性能。

  4. 服務器永遠不會忘記每一個客戶端身份」,由於客戶端會在每一個請求中發送全部必要的信息。(攜帶token)

    那麼無狀態又要怎麼實現呢?前面咱們已經說了,服務端不該該再保存session會話,這個工做所有交由http請求去標識,而最多見的作法則是使用token。生成token能夠考慮使用jwt,oauth。其中jwt能夠參考個人另外一篇文章:www.jianshu.com/p/6ff0e30fc…

總結

咱們首先介紹rest服務背景,引出rest架構的介紹,最後重點介紹了rest api的約束設計。

關注我,這裏只有乾貨!

相關文章
相關標籤/搜索