淺析RESTful風格的API

要說RESTful首先來說說REST – REpresentational State Transfer (表述性狀態傳遞)

表述性狀態轉移是一組架構約束條件和原則。滿足這些約束條件和原則的應用程序或設計就是RESTful。需要注意的是,REST是設計風格而不是標準。

以上的概念大概是許多關於RESTful中都會出現的定義概念。那麼什麼是表述性狀態轉移呢?首先,之所以晦澀是因爲前面主語被去掉了,全稱是 Resource Representational State Transfer:通俗來講就是:資源在網絡中以某種表現形式進行狀態轉移。在查詢很多資料後看到一句很精簡的總結:

URL定位資源,用HTTP動詞(GET,POST,DELETE,PUT等)描述操作。

既然說到了是用HTTP動詞進行操作。那麼需要了解這裏列出的4.5個非常重要的HTTP動作,這裏的0.5個是指PATCH,因爲它在功能上與PUT非常類似,剩下4個通常被API開發人員兩兩結合使用

  • GET(SELECT):從服務器獲取一個指定資源或一個資源集合;
  • POST(CREATE):在服務器上創建一個資源;
  • PUT(UPDATE):更新服務器上的一個資源,需要提供整個資源;
  • PATCH(UPDATE):更新服務器上的一個資源,只提供資源中改變的那部分屬性;
  • DELETE(DELETE):移除服務器上的一個資源;

還有兩個不常見的HTTP動作:

  • HEAD – 獲取一個資源的元數據,例如一組hash數據或者資源的最近一次更新時間;
  • OPTIONS – 獲取當前用戶(Consumer)對資源的訪問權限;

關於RESTful的API設計風格,說完RESTful接下來該說說API了。

API是服務提供方和使用方之間的契約,打破該契約將會給服務端開發人員招來非常大的麻煩,這些麻煩來自於使用API的開發人員,因爲對API的改動會導致他們的移動app無法工作。一個好的文檔對於解決這些事情能起到事半功倍的作用,但是絕對多數程序員都不喜歡寫文檔。如果想讓服務端的價值更好的體現出來,就要好好設計API。通過這些API,你的服務/核心程序將有可能成爲其他項目所依賴的平臺;你提供的API越易用,就會有越多人願意使用它。規劃API的展示形式可能比你想象的要簡單,首先要確定你的數據是如何設計以及核心程序是如何工作的。
這裏寫圖片描述
也就是說Server提供的RESTful API中,URL中只使用名詞來指定資源,原則上不使用動詞。“資源”是REST架構或者說整個網絡處理的核心。

那麼下面來具體說說如何形成良好的RESTful風格的API設計

1. 使用名詞而不是動詞
Server提供的RESTful API中,URL中只使用名詞來指定資源,原則上不使用動詞。“資源”是REST架構或者說整個網絡處理的核心。比如:

2.Get方法和查詢參數不應該涉及狀態改變
使用PUT, POST 和DELETE 方法 而不是 GET 方法來改變狀態,不要使用GET 進行狀態改變:
通常,GET請求能夠被瀏覽器緩存(而且通常都會這麼做),例如,當用戶發起第二次POST請求時,緩存的GET請求(依賴於緩存首部)能夠加快用戶的訪問速度。一個HEAD請求基本上就是一個沒有返回體的GET請求,因此也能被緩存。

3.使用複數名詞
不要混淆名詞單數和複數,爲了保持簡單,只對所有資源使用複數。

4. 使用子資源表達關係
如果一個資源與另外一個資源有關係,使用子資源:

5.使用Http頭聲明序列化格式
在客戶端和服務端,雙方都要知道通訊的格式,格式在HTTP-Header中指定
Content-Type 定義請求格式
Accept 定義系列可接受的響應格式

6.使用HATEOAS
Hypermedia as the Engine of Application State 超媒體作爲應用狀態的引擎,超文本鏈接可以建立更好的文本瀏覽:

7.爲集合提供過濾 排序 選擇和分頁等功能
Filtering過濾:

使用唯一的查詢參數進行過濾:

GET /cars?color=red 返回紅色的cars
GET /cars?seats<=2 返回小於兩座位的cars集合

當用戶請求獲取一組對象列表時,你就需要對結果進行過濾並返回一組嚴格符合用戶要求的對象。有時返回結果的數量可能非常大,但是你也不能隨意對此進行約束,因爲這種服務端的隨意約束會造成第三方開發人員的困惑。如果用戶請求了一個集合,並對返回結果進行遍歷,然後只要前100個對象,那麼這裏就需要由用戶來指明這個限制量。這樣用戶就不會有這樣的疑惑:是他們程序的bug還是接口限制了100條?還是網絡只允許傳這麼大的包?

Sorting排序:

允許針對多個字段排序

GET /cars?sort=-manufactorer,+model

這是返回根據生產者降序和模型升序排列的car集合

Field selection

移動端能夠顯示其中一些字段,它們其實不需要一個資源的所有字段,給API消費者一個選擇字段的能力,這會降低網絡流量,提高API可用性。

GET /cars?fields=manufacturer,model,id,color

Paging分頁

使用 limit 和offset.實現分頁,缺省limit=20 和offset=0;

GET /cars?offset=10&limit=5

爲了將總數發給客戶端,使用訂製的HTTP頭: X-Total-Count.

鏈接到下一頁或上一頁可以在HTTP頭的link規定,遵循Link規定:

Link: https://blog.mwaysolutions.com/sample/api/v1/cars?offset=15&limit=5; rel=”next”,
https://blog.mwaysolutions.com/sample/api/v1/cars?offset=50&limit=3; rel=”last”,
https://blog.mwaysolutions.com/sample/api/v1/cars?offset=0&limit=5; rel=”first”,
https://blog.mwaysolutions.com/sample/api/v1/cars?offset=5&limit=5; rel=”prev”,

8.版本化你的API
也就是進行版本控制。無論你在設計什麼系統,也不管你事先做了多麼詳盡的計劃,隨着時間的推移和業務的發展,你的程序總會發生變化,數據關係也會發生變化,資源可能會被添加或者刪除一些屬性。只要軟件還在生存期內並且還有人在用它,開發人員就得面對這些問題,對於API設計來說,尤其如此。

在URL中加入版本號是一個優秀的API設計,當然還有另一個常用的解決辦法就是把版本號放在請求首部中

使得API版本變得強制性,不要發佈無版本的API,使用簡單數字,避免小數點如2.5。一般在Url後面使用?v

/blog/api/v1

9. 使用Http狀態碼處理錯誤
如果你的API沒有錯誤處理是很難的,只是返回500和出錯堆棧不一定有用

Http狀態碼提供70個出錯,我們只要使用10個左右:

200 – OK – 一切正常
201 – OK – 新的資源已經成功創建
204 – OK – 資源已經成功擅長

304 – Not Modified – 客戶端使用緩存數據

400 – Bad Request – 請求無效,需要附加細節解釋如 “JSON無效”
401 – Unauthorized – 請求需要用戶驗證
403 – Forbidden – 服務器已經理解了請求,但是拒絕服務或這種請求的訪問是不允許的。
404 – Not found – 沒有發現該資源
422 – Unprocessable Entity – 只有服務器不能處理實體時使用,比如圖像不能被格式化,或者重要字段丟失。

500 – Internal Server Error – API開發者應該避免這種錯誤。

1XX的返回碼預留給HTTP的底層使用,在你的整個職業生涯中都不會主動發送這種返回碼;

2XX的返回碼錶示請求按照預期執行併成功返回了信息。服務端要儘可能給用戶返回這種結果。

3XX的返回碼錶示請求重定向,大多數API都不會經常使用這種請求(),但是最新的超媒體API會充分使用這些功能。

4XX的返回碼主要表示由客戶端引起的錯誤,例如請求參數錯誤或者訪問一個不存在的資源,這些必須爲冪等操作,並且不能改變服務器的狀態(其實服務器的狀態發生了改變就意味着操作不是冪等了)。

5XX的返回碼主要表示由服務器引起的錯誤,通常情況下,這些錯誤都是開發人員

使用詳細的錯誤包裝錯誤:

{

  "errors": [

   {

    "userMessage": "Sorry, the requested resource does not exist",

    "internalMessage": "No car found in the database",

    "code": 34,

    "more info": "http://dev.mwaysolutions.com/blog/api/v1/errors/12345"

   }

  ]

}

10.允許覆蓋http方法
一些代理只支持POST 和 GET方法, 爲了使用這些有限方法支持RESTful API,需要一種辦法覆蓋http原來的方法。

使用訂製的HTTP頭 X-HTTP-Method-Override 來覆蓋POST 方法.

發佈了35 篇原創文章 · 獲贊 97 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章