REST即表述性狀態傳遞(英文:Representational State Transfer,簡稱REST)是Roy Fielding博士在2000年他的博士論文中提出來的一種軟體架構風格 ...
1. REST的由來
REST即表述性狀態傳遞(英文:Representational State Transfer,簡稱REST)是Roy Fielding博士在2000年他的博士論文中提出來的一種軟體架構風格。
上世紀90年代面對高速發展的互聯網規模,HTTP1.0需要進一步改進。Roy Fielding 著手制定HTTP1.1的標準及後續擴展工作。HTTP1.1重視降低WEB系統開發的複雜性(通過增強HTTP的請求頭和響應頭),提高系統的可擴展性(通過更容易的緩存指令)以及其他性能優化工作(比如長連接和多個請求和響應可以重疊等)。
Roy Fielding在制定HTTP時有一個願景:Web世界的應用程式應隨著不斷的超連接跳轉來實現應用系統狀態遷移,所以HTTP應該是一個應用協議,而不是一個純粹的超文本傳輸協議。
這就是REST的由來。當我們在談論REST的時候,表示我們在談論Web世界的應用一種基於HTTP的架構風格。
2. REST的構成
2.1. 資源
在restful中資源是核心抽象,任何會被互聯網組件訪問的信息都是資源,並用一個URL/URN來標識。
舉例來說,獲取某網站的2017年10月1號的天氣信息,該網站可以命名改信息為http://www.somesite.com/weather/2017/10/1或者 http://www.somesite.com/weather?year=2017&month=10&day=1
。客戶端瀏覽器能用GET方法合法的獲取該資源。
如果天氣採集人員要創建2017年10月1號的天氣信息,則用POST方法提交表單給http://www.somesite.com/weather
完成創建資源工作。
http://www.somesite.com/weather
並沒有制定哪一天的天氣信息,但它確實資源,這體現資源的抽象性。
2.2. 資源的表述
資源的表述是指資源的表現形式,這些形式由請求方和資源提供方通過HTTP協商指定。包括以下內容:
2.2.1. MIME(Multipurpose Internet Mail Extensions)
MIME是多用途互聯網郵件擴展類型,它是一個互聯網標準,擴展了電子郵件標準,使其能夠支持:
非ASCII字元文本;非文本格式附件(二進位、聲音、圖像等);由多部分(multiple parts)組成的消息體;包含非ASCII字元的頭信息(Header information)。
比如下圖,客戶端表示能接受json(首選),text(次選)以及任意格式(再次選);伺服器端返回json內容給客戶端:
2.2.2. 緩存約定
所以的資源操作包括讀取和更新操作,對於不頻繁更新的數據數據多數可以進行緩存。這種換成越靠近客戶端,用戶體驗越好,即提高了整體系統的可用性。
HTTP採取多層緩存機制,系統可以定義自己的緩存策略。(此處是否需要講公共緩存,私有緩存,運行機制?)
其中代理伺服器和緩存伺服器應該只對公共緩存表述進行緩存,瀏覽器緩存對公共和私有的緩存表述都能進行緩存。通常代理伺服器的緩存行為是用戶所屬組織支持的,不屬於應用系統的行為。
2.3. 資源的自描述
資源的自描述是指:資源的表述裡面應該包括資源當前狀態的描述,以及對該資源或相關資源進一步操作的超鏈接。
2.3.1. 資源的當前狀態
資源的當前狀態由以下幾項共同組成:
- 屬於該資源的信息項目的值,比如訂單的編號,創建日期。
- 相關資源的鏈接,比如訂單的客戶鏈接以及訂單明細鏈接。
- 表示資源將來會遷移到某種可能狀態的鏈接,比如遷移到完成狀態的鏈接:/order/1/completeness POST
- 對應該資源與其他資源相關聯的任何業務規則的求值結果,比如訂單統計表:/order/statistics/year/2017 GET
下圖是一個訂單狀態的json表述:
2.3.2. 操作資源的統一介面
HTTP的初衷是應用層協議,HTTP是REST風格的。HTTP的動作提供了操作字體的統一介面。
動作 | 介面作用 | 重覆操作效果 |
---|---|---|
POST | 創建資源 | 不冪等 |
PUT | 整體更新資源 | 冪等 |
PATCH | 部分更新資源 | 不冪等 |
DELETE | 刪除資源 | 冪等 |
GET | 獲取資源 | 冪等 |
冪等 表示動作的重覆執行不會再產生副作用(引起資源狀態變化),比如刪除一個資源後再次刪除也不會產生作用,同時系統也不應該返回錯誤信息,而是總是返回成功。
RPC或者SOAP風格的架構下HTTP是作為傳輸協議使用。
2.3.3. 請求的無狀態
REST的無狀態是指客戶端請求伺服器時,應提供足夠的信息以讓伺服器能理解並提供服務。無狀態的好處包括:
- 改善可見性(監視系統不必為了確定一個請求的全部性質而去查看請求之外的其他請求)
- 改善可靠性(減輕了從局部故障中恢復的任務量)
- 改善可伸縮性(服務端不必在多個請求直接保存狀態,從而允許伺服器迅速釋放資源)
缺點:
- 由於伺服器不能保持會話狀態數據,則會造成在每一次請求中發送大量重覆的數據,可能會降低網路性能。
下圖是請求有狀態和無狀態的對比例子:
2.4. HATEOAS
HATEOAS(The Hypermedia As The Engine Of Application Statue),中文意思是“將超媒體作為應用狀態的引擎”,這是REST的最高目標(也叫主要架構約束)。
HATEOAS包括兩個概念:
- 應用狀態由應用(系統)中的各資源狀態組成,資源狀態的變化導致應用狀態的變化。
- 通過在資源表述中添加狀態遷移的超鏈接引導客戶端改變資源狀態。
比如:銷售訂單在創建後,客戶端通過GET操作獲取一個訂單信息,然後請求“審批訂單”鏈接使訂單變成“已審批“狀態。客戶端再請求”執行訂單“完成訂單。這就是一個簡單工作流程。
3. REST與分散式事物
分散式系統中事物是一個重要話題,遺憾的是REST作為一種系統風格,並沒有約定對事物管理進行規定。事物是伺服器端的事情,不論採用何種事物處理方式都要避免對客戶使用rest服務的影響。
4. REST的典型應用案例
1. GitHub Developer API
比如API:列出pull的評論
GET /repos/:owner/:repo/pulls/:number/reviews
官網: https://developer.github.com/v3/pulls/reviews/
2. LinkIn 開發者中心
比如API:獲取當前用戶的信息
GET /v1/people/~?
官網:https://developer.linkedin.com/zh-cn/docs/rest-api
5. REST vs RPC
REST式的Web服務和RPC式的Web服務在介面定義上的區別是,REST使用HTTP通用方法作為統一介面的標準辭彙,REST式的Web服務所提供的方法信息都在HTTP方法里,而RPC式的web服務所提供的方法信息在SOAP/HTTP信封里(其封裝的格式通常是HTTP或者是SOAP),每個RPC式的web服務都會公佈一套符合自己商業邏輯的方法辭彙。
RPC的典型案例
1. 百度lbs服務API
比如API: 行政區劃區域檢索,之所以是rpc,是由於:
- 在參數中指定了資源格式MIME(此例是json),就是說資源表述由百度官方自定義協議解釋。
- 返回狀態和錯誤信息封裝在返回結果中,說明對於錯誤處理也由百度官方自定義協議解釋。
- 返回結果關心的是滿足當前介面數據,如果想進一步瞭解街道信息,客戶端鬚根據獲取街道信息API定義獲取。
http://api.map.baidu.com/place/v2/search?query=ATM機&tag=銀行®ion=北京&output=json&ak=您的ak GET
如果經過rest風格改造,行政區劃區域檢索API的返回結果可以是如下形式:
註:百度lbs不是面嚮應用狀態遷移設計,因此採用rpc也是合適的。
2.Saleforce SOAP API
Saleforce提供了SOAP(簡單對象訪問協議) API,SOAP 通過發佈WSDL(網路服務描述語言)文件來描述伺服器提供的API的輸入參數結構和返回數據結構以及可能的異常信息。客戶端通過WSDL生成客戶端調用代碼(SOAP語言無關,可跨開發語言調用),就能調用遠程的服務API。
下圖表示表示了Saleforce的提供的API的WSDL:
註:Saleforce也提供了REST的API。
以下是二者的主要區別:
REST | RPC | |
---|---|---|
HTTP協議地位 | 應用協議 | 傳輸協議或者不用 |
傳輸協議 | HTTP | HTTP或者TCP |
消息序列化類型 | MIME | MIME或者自定義協議 |
傳輸性能 | 中 | 高 |
服務處理性能 | 中 | 高 |
介面特點 | 通用(HTTP動作) | 自定義介面動作 |
應用協議 | HTTP | 自定義 |
應用狀態遷移方式 | 資源狀態變化 | 業務數據狀態變化 |
緩存擴展性 | 強 | 自定義 |
客戶端耦合力度(協議) | 弱 | 強 |
客戶端代碼執行 | 按需提供(JS,CSS,HTML等) | 預設不支持 |
客戶端的庫支持 | 不需要 | 最好有,且和服務同步升級 |
防火牆穿透力 | 強 | 預設不支持 |
公網組件支持度 | 現成支持,包括(反向)代理伺服器,防火牆,緩存伺服器,用戶代理(瀏覽器等) | 需自行支持(http傳輸除外) |
企業應用標準化程度 | 低(企業自定義) | 中(基於SOAP協議,各廠商產品容易集成) |
以下是主流RPC和REST框架
框架 | 特點 | 開發語言 |
---|---|---|
Thrift | Thrift是一個跨語言的RPC框架,自帶的代碼生成引擎大幅提高了開發效率,從而使它如此流行。 最初由Facebook團隊設計開發,現在已貢獻給Apache |
多語言 |
Dubbo | Dubbo是阿裡巴巴開源的專門為Java設計的、成熟的RPC框架。支持基本的服務治理,所有服務治理 功能均在Client端集成:服務發現、負載均衡、容錯、監控等 |
Java |
Spring HATEOAS | Spring HATEOAS 可以很方便創建 基於HATEOAS 原則的REST 風格介面 , 但需要依賴於 Spring 和 Spring MVC |
Java |
6. 總結
HTTP的本意是方便應用系統實現REST的架構,不過人們在早期並沒有意識到它的優點,因此目前更多使用的是RPC框架,因為REST 對開發人員的能力要求更高。綜上,REST具有以下主要特點:
- 以HTTP為應用協議。
- 基於WEB中間件進行擴展:緩存代理提高緩存擴展,反向代理提供負載均衡和內外網協議轉化(HTTPS和HTTP之間)。
- 請求的無狀態:由於伺服器沒有會話上下文信息,提高系統的可伸縮性。缺點是傳輸冗餘一些。
- 多級緩存:客戶端代理,代理伺服器,緩存伺服器提供了強大緩存能力,提高了系統的可用性。
- 對資源內容的描述方式,比如MIME協商或者在此基礎上的擴展格式,保證了系統的簡單性和通用性。
- 資源狀態變化促成應用狀態遷移(HATEOAS),可使開發者以資源為中心建模,這種設計相對簡單。
- 資源表述中鏈接廣告了應用的狀態流,但並不強迫客戶端進行處理,有利於客戶端平滑升級。