你構建的API夠RESTful嗎?

背景

很多團隊都在構建API,并且聲稱自己團隊創(chuàng)建的API都是足夠的RESTful,今天我們簡單聊下RESTful API相關的一些概念和設計實踐。

定義

REST(Representational State Transfer) - 表述性狀態(tài)轉移

簡單一句是就指: 服務器發(fā)送表述用于描述資源的當前狀態(tài),客戶端發(fā)送表述用于描述客服端希望資源擁有的狀態(tài)。

REST 是一種架構風格。定義了分布式系統(tǒng)中,各個組件之間的交互方式。

Richardson成熟度模型

image.png
  • LEVEL 0, 只用HTTP作為傳輸通道,不會使用HTTP的任何額外機制。例如SOAP、 RPC
  • LEVEL 1, 引入資源的概念,使用不同的URI完成不同的功能。
GET /books?author=“john”

Response:
[
{“id”:11, “Game of thrones”},
{“id”:22, “Notre Dame de Paris”}
]

GET /orders?action=create&bookId=11&quantity=2

Response:
{
“id”: 3,
“book-id”: 11,
“quantity”: 2
}

GET /orders/3/delete
  • LEVEL 2, 用不同的URI定位資源,用不同的HTTP方法操作資源-CRUD。
GET /books?author=“john”

200 OK
[
{“id”:11, “Game of thrones”},
{“id”:22, “Notre Dame de Paris”}
]

POST /orders
{
“bookId”: 11
“quantity”: 2,
}

201 CREATED
Location: /orders/3
 
{
“id”: “3”
“bookId”: 11
“quantity”: 2
}

DELETE /orders/3
  • LEVEL 3 - HATEOAS, 在返回的Representation中包含了與該資源相關資源的鏈接, 降低客戶端編程錯誤(大約90%的錯誤出現(xiàn)在為服務器構造正確URI的過程中), 減少無效的狀態(tài)轉換調(diào)用。
GET /books?author=“john”

200 OK
{
“data”: {
[
{“id”:11, “Game of thrones”},
{“id”:22, “Notre Dame de Paris”}
]
},
“l(fā)inks”: {
“self”: “/books?author=john”
“order”: “/orders”
}
}

POST /orders
{
“bookId”: 11
“quantity”: 2,
}

201 CREATED
Location: /orders/3
 
{
“data”:{
“id”: “3”
“bookId”: 11
“quantity”: 2
},
“l(fā)inks”: {
“self”: “/orders/3”,
“payment”: “/payments?discount=95”
}
}

DELETE /orders/3

對照以上的成熟度模型,我們可以比較明確的知道我們自己的API,屬于哪個LEVEL?

API規(guī)范

無狀態(tài)原則

服務端必須是沒有狀態(tài)的,換句話說,客戶端的所有請求必須包括服務端完成請求的所有信息(e.g: 認證信息,表單數(shù)據(jù));客戶端不能假設服務端有任何的狀態(tài)信息,所有的狀態(tài)信息只有兩種方式保持:

  • 資源狀態(tài)
  • 客戶端保存

服務無狀態(tài),很好的方便了水平擴展,高可用。

冪等原則

一次和多次請求某一個資源應該具有相同的副作用

冪等的方法意味著請求成功執(zhí)行所得到的結果不依賴于該方法被執(zhí)行的次數(shù);這在分布式事務-特別是最終一致性的時候,我們都需要保證業(yè)務服務的冪等性息息相關。

在常見的HTTP Verbs里面,GET是天然的滿足冪等性,為緩存提供了條件;DELETE和PUT/PATCH都可以實現(xiàn)冪等。

可緩存原則

在請求和響應的過程中,任何一個節(jié)點都可能會”緩存“響應數(shù)據(jù), 因此響應都會顯式或者隱式的包含”能否被緩存“的信息, 客服端和中間涉及的節(jié)點會根據(jù)這些信息,來進行后續(xù)處理。
比如: 服務端可以使用Cache-Control等Http Header字段來控制緩存的期限,良好的緩存策略可以減少客戶端-服務端的交互,降低服務端的負載,從而提供性能和可擴展性。

HTTP/1.1 200 OK
Date: Fri, 26 Mar 2018 09:33:49 GMT
Cache-Control: max-age=3600 
Last-Modified: Fri, 26 Mar 2018 09:33:49 GMT 
ETag: cde893c4

安全原則

在做API設計的的時候,以下是在實際開發(fā)中常遇到的安全問題:

  • 缺失了對資源從屬關系的檢查,對于URL中只出現(xiàn)一個資源的情況,絕大多數(shù)開發(fā)者都會知道做安全防御,然而,問題往往出現(xiàn)在包括多個資源的時候,e.g: /users/1/orders/239843,應用只檢查了當前請求發(fā)起者是否是編號 為1的用戶,以及編號為239843的訂單是否存在,有很大的概率沒有檢查URL中的訂單和用戶之間的從屬關系
  • HTTP響應中缺失必要的Security Header, 請合理使用以下的Header,可使得你開發(fā)的API具備更高的安全性。
    • X-XSS-Protection
    • Strict-Transport-Security
    • X-Content-Type-Options
    • X-Frame-Options
  • 泄露業(yè)務信息,在返回體中,不要暴露多余的信息,特別是銘感信息。
  • API缺乏速率限制的保護

兼容性原則

  • 當API出現(xiàn)較大升級并且包含破壞性改動的時候,服務提供者需要提供新的API版本,與此同時,需要保持對老版本API的支持,直到達到棄用的標準。
    • 常將API版本放在URL中,比如/v2/users/{uid};
    • 或者放在http header中, Accept: application/vnd.api+json;version=2
  • 在更改已有API的時候,不能更改字段的含義,只添加可選字段,不添加必選字段,當資源URL發(fā)生變化的時候,支持重定向。

API設計

API的設計遵循上面的四個原則,同時需要根據(jù)業(yè)務定義資源,用URI定位資源,并用HTTP verb來操作資源。

定義Resource

一切可以被命名的信息都可以叫做資源(Resource),資源是名詞,不要是動詞,e.g: 一個用戶關注了另一個用戶,這個資源應該被定義成“關系(relationship)”,而不是“關注(follow)”。

用URI定位資源

GET /users/{id}
POST /users
PUT/PATCH /users/{id}
DELETE /users/{id}

在我們團隊中,定義了設計URL的軍規(guī)

  • 使用復數(shù),不管它代表的是一個資源還是一個資源集合 GET /users/123/orders/345
  • 使用“-”,分離多個單詞,而不是駝峰, e.g: GET /users/{id}/account-type

JSON-API

最后,開發(fā)API的過程中,會花很多時間去和API的消費者溝通API接口的具體格式。例如Content-Type,JSON的字段的定義等等,需要耗費大量的精力,如果遵循共同的約定,可以提高開發(fā)效率,利用更普遍的工具,使開發(fā)者更加專注于開發(fā)重點,這里向大家推薦:JSON API Specification: http://jsonapi.org

  • meta:輔助信息
  • data:主體信息
  • attributes:資源的數(shù)據(jù)
  • errors:錯誤
  • links:鏈接
GET /users/123
{
”meta”: {…},
“data”: {
“type”: “user”,
“id”: “123”,
“attributes”: {},
“relationships”: {},
},
“errors”: [],
“l(fā)inks”: {…},
“included”: {…}
}

參考

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

相關閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,545評論 19 139
  • API定義規(guī)范 本規(guī)范設計基于如下使用場景: 請求頻率不是非常高:如果產(chǎn)品的使用周期內(nèi)請求頻率非常高,建議使用雙通...
    有涯逐無涯閱讀 2,925評論 0 6
  • 去年有段時間得空,就把谷歌GAE的API權威指南看了一遍,收獲頗豐,特別是在自己幾乎獨立開發(fā)了公司的云數(shù)據(jù)中心之后...
    騎單車的勛爵閱讀 21,095評論 0 41
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong閱讀 22,939評論 1 92
  • 我是這樣應對知識焦慮的 最近有兩點感觸: 第一,隨著中國創(chuàng)新浪潮來臨,學校所學知識與社會所需知識脫節(jié)速度加快。 第...
    漫雪封塵閱讀 658評論 1 3

友情鏈接更多精彩內(nèi)容