1. 程式人生 > >理解RESTful 架構

理解RESTful 架構

restfu tle tran 什麽 rtb info 接口 調用 崩潰

REST是所有Web應用都應該遵守的架構設計指導原則。
Representational State Transfer,翻譯是”表現層狀態轉化”。
面向資源是REST最明顯的特征,對於同一個資源的一組不同的操作。資源是服務器上一個可命名的抽象概念,資源是以名詞為核心來組織的,首先關註的是名詞。REST要求,必須通過統一的接口來對資源執行各種操作。對於每個資源只能執行一組有限的操作。(7個HTTP方法:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS)

什麽是RESTful API?

符合REST架構設計的API。

總結

符合REST設計標準的API,即RESTful API。REST架構設計,遵循的各項標準和準則,就是HTTP協議的表現,換句話說,HTTP協議就是屬於REST架構的設計模式。比如,無狀態,請求-響應。。。

參考:
理解本身的REST架構風格
http://www.infoq.com/cn/articles/understanding-restful-style/

理解RESTful架構
http://www.ruanyifeng.com/blog/2011/09/restful.html

Restful API設計指南
http://www.ruanyifeng.com/blog/2014/05/restful_api.html

二、Restful api接口有什麽特征?

REST描述的是在網絡中client和server的一種交互形式;REST本身不實用,實用的是如何設計 RESTful API(REST風格的網絡接口)。

1.URL的根路徑

http://api.chesxs.com/v1

2.需要有api版本信息

http://api.chesxs.com/v1

3.URL中只使用名詞指定資源,不用動詞,且推薦使用復數

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

http://api.chesxs.com/v1/cars // 獲取某個賬戶下的車輛列表
http://api.chesxs.com/v1/fences // 獲取某個賬戶下的圍欄列表

4. 用HTTP協議裏的動詞來實現資源的添加,修改,刪除等操作。即通過HTTP動詞來實現資源的狀態扭轉

技術分享圖片
GET 用來獲取資源,
POST 用來新建資源(也可以用於更新資源)。比如:POST http://api.chesxs.com/v1/car: 添加車輛
PUT 用來更新資源,
DELETE 用來刪除資源。比如:DELETE http://api.chesxs.com/v1/cars 刪除某輛車 (在http parameter指定好友id) 
UPDATE http://api.chesxs.com/v1/fence 更新圍欄信息

錯誤使用: GET http://api.chesxs.com/v1/deleteCar 刪除車輛
技術分享圖片

5.GET應該是安全的,不會改變資源狀態

這個應該很好理解,get的時候就只是獲取資源,而不涉及添加、更新、刪除資源。

6.使用正確的HTTP Status Code返回狀態碼

常用的有404,200,500,400等等。

7.過濾信息

如果記錄數量很多,服務器不可能都將它們返回給用戶。API應該提供參數,過濾返回結果。

下面是一些常見的參數。

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

8.規範返回的數據

為了保障前後端的數據交互的順暢,建議規範數據的返回,並采用固定的數據格式封裝。

接口返回模板:

技術分享圖片
{
    status:0,

    data:{}||[],

    msg:’’
}

REST架構風格的推導過程如下圖所示:

圖1:REST所繼承的架構風格約束(原圖可在這裏下載)

技術分享圖片

在圖1中,每一個橢圓形裏面的縮寫詞代表了一種架構風格,而每一個箭頭邊的單詞代表了一種架構約束。

REST架構風格最重要的架構約束有6個:

  • 客戶-服務器(Client-Server)

通信只能由客戶端單方面發起,表現為請求-響應的形式。

  • 無狀態(Stateless)

通信的會話狀態(Session State)應該全部由客戶端負責維護。

  • 緩存(Cache)

響應內容可以在通信鏈的某處被緩存,以改善網絡效率。

  • 統一接口(Uniform Interface)

通信鏈的組件之間通過統一的接口相互通信,以提高交互的可見性。

  • 分層系統(Layered System)

通過限制組件的行為(即,每個組件只能“看到”與其交互的緊鄰層),將架構分解為若幹等級的層。

  • 按需代碼(Code-On-Demand,可選)

支持通過下載並執行一些代碼(例如Java Applet、Flash或JavaScript),對客戶端的功能進行擴展。

在論文中推導出的REST架構風格如下圖所示:

圖2:REST架構風格(原圖可在這裏下載)

技術分享圖片

而HTTP/1.1協議作為一種REST架構風格的架構實例,其架構如下圖所示:

圖3:一個基於REST的架構的過程視圖(原圖可在這裏下載)

技術分享圖片

用戶代理處在三個並行交互(a、b和c)的中間。用戶代理的客戶端連接器緩存無法滿足請求,因此它根據每個資源標識符的屬性和客戶端連接器的配置,將每個請求路由到資源的來源。請求(a)被發送到一個本地代理,代理隨後訪問一個通過DNS查找發現的緩存網關,該網關將這個請求轉發到一個能夠滿足該請求的來源服務器,服務器的內部資源由一個封裝過的對象請求代理(object request broker)架構來定義。請求(b)直接發送到一個來源服務器,它能夠通過自己的緩存來滿足這個請求。請求(c)被發送到一個代理,它能夠直接訪問WAIS(一種與Web架構分離的信息服務),並將WAIS的響應翻譯為一種通用的連接器接口能夠識別的格式。每一個組件只知道與它們自己的客戶端或服務器連接器的交互;整個過程拓撲是我們的視圖的產物。

通過比較圖2和圖3,讀者不難發現這兩張圖中的架構是高度一致的。對於HTTP/1.1協議為何要設計成這個樣子,讀者想必已經有所領悟。

在論文的第六章中,Fielding對於到2000年為止在Web基礎架構協議的設計和開發方面的一些經驗教訓進行了深入的分析。其中,“HTTP不是RPC”、“HTTP不是一種傳輸協議”兩部分值得讀者反復閱讀。時至13年之後的今日,對於HTTP協議的誤解仍然廣泛存在。

以上簡要介紹了Fielding博士論文中的內容。為了幫助讀者仔細閱讀Fielding的博士論文,筆者整理了一套Fielding博士論文的導讀,將在本專欄後續文章中載出。

REST詳解

REST究竟是什麽?因為REST的內涵非常豐富,所以很難用一兩句話解釋清楚這個問題。

首先,REST是Web自身的架構風格。REST也是Web之所以取得成功的技術架構方面因素的總結。REST是世界上最成功的分布式應用架構風格(成功案例:Web,還不夠嗎?)。它是為 運行在互聯網環境 的 分布式 超媒體系統量身定制的。互聯網環境與企業內網環境有非常大的差別,最主要的差別是兩個方面:

  • 可伸縮性需求無法控制:並發訪問量可能會暴漲,也可能會暴跌。

  • 安全性需求無法控制:無法控制客戶端發來的請求的格式,很可能會是惡意的請求。

而所謂的“超媒體系統”,即,使用了超文本的系統。可以把“超媒體”理解為超文本+媒體內容。

REST是HTTP/1.1協議等Web規範的設計指導原則,HTTP/1.1協議正是為實現REST風格的架構而設計的。新的Web規範,其設計必須符合REST的要求,否則整個Web的體系架構會因為引入嚴重矛盾而崩潰。這句話不是危言聳聽,做個類比,假如蘇州市政府同意在市區著名園林的附近大型土木,建造大量具有後現代風格的摩天大樓,那麽不久之後世界聞名的蘇州園林美景將不復存在。

上述這些關於“REST是什麽”的描述,可以總結為一句話:REST是所有Web應用都應該遵守的架構設計指導原則。當然,REST並不是法律,違反了REST的指導原則,仍然能夠實現應用的功能。但是違反了REST的指導原則,會付出很多代價,特別是對於大流量的網站而言。

要深入理解REST,需要理解REST的五個關鍵詞:

  1. 資源(Resource)
  2. 資源的表述(Representation)
  3. 狀態轉移(State Transfer)
  4. 統一接口(Uniform Interface)
  5. 超文本驅動(Hypertext Driven)

什麽是資源?

資源是一種看待服務器的方式,即,將服務器看作是由很多離散的資源組成。每個資源是服務器上一個可命名的抽象概念。因為資源是一個抽象的概念,所以它不僅僅能代表服務器文件系統中的一個文件、數據庫中的一張表等等具體的東西,可以將資源設計的要多抽象有多抽象,只要想象力允許而且客戶端應用開發者能夠理解。與面向對象設計類似,資源是以名詞為核心來組織的,首先關註的是名詞。一個資源可以由一個或多個URI來標識。URI既是資源的名稱,也是資源在Web上的地址。對某個資源感興趣的客戶端應用,可以通過資源的URI與其進行交互。

什麽是資源的表述?

資源的表述是一段對於資源在某個特定時刻的狀態的描述。可以在客戶端-服務器端之間轉移(交換)。資源的表述可以有多種格式,例如HTML/XML/JSON/純文本/圖片/視頻/音頻等等。資源的表述格式可以通過協商機制來確定。請求-響應方向的表述通常使用不同的格式。

什麽是狀態轉移?

狀態轉移(state transfer)與狀態機中的狀態遷移(state transition)的含義是不同的。狀態轉移說的是:在客戶端和服務器端之間轉移(transfer)代表資源狀態的表述。通過轉移和操作資源的表述,來間接實現操作資源的目的。

什麽是統一接口?

REST要求,必須通過統一的接口來對資源執行各種操作。對於每個資源只能執行一組有限的操作。以HTTP/1.1協議為例,HTTP/1.1協議定義了一個操作資源的統一接口,主要包括以下內容:

  • 7個HTTP方法:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS

  • HTTP頭信息(可自定義)

  • HTTP響應狀態代碼(可自定義)

  • 一套標準的內容協商機制

  • 一套標準的緩存機制

  • 一套標準的客戶端身份認證機制

REST還要求,對於資源執行的操作,其操作語義必須由HTTP消息體之前的部分完全表達,不能將操作語義封裝在HTTP消息體內部。這樣做是為了提高交互的可見性,以便於通信鏈的中間組件實現緩存、安全審計等等功能。

什麽是超文本驅動?

“超文本驅動”又名“將超媒體作為應用狀態的引擎”(Hypermedia As The Engine Of Application State,來自Fielding博士論文中的一句話,縮寫為HATEOAS)。將Web應用看作是一個由很多狀態(應用狀態)組成的有限狀態機。資源之間通過超鏈接相互關聯,超鏈接既代表資源之間的關系,也代表可執行的狀態遷移。在超媒體之中不僅僅包含數據,還包含了狀態遷移的語義。以超媒體作為引擎,驅動Web應用的狀態遷移。通過超媒體暴露出服務器所提供的資源,服務器提供了哪些資源是在運行時通過解析超媒體發現的,而不是事先定義的。從面向服務的角度看,超媒體定義了服務器所提供服務的協議。客戶端應該依賴的是超媒體的狀態遷移語義,而不應該對於是否存在某個URI或URI的某種特殊構造方式作出假設。一切都有可能變化,只有超媒體的狀態遷移語義能夠長期保持穩定。

一旦讀者理解了上述REST的五個關鍵詞,就很容易理解REST風格的架構所具有的6個的主要特征:

  • 面向資源(Resource Oriented)

  • 可尋址(Addressability)

  • 連通性(Connectedness)

  • 無狀態(Statelessness)

  • 統一接口(Uniform Interface)

  • 超文本驅動(Hypertext Driven)

這6個特征是REST架構設計優秀程度的判斷標準。其中,面向資源是REST最明顯的特征,即,REST架構設計是以資源抽象為核心展開的。可尋址說的是:每一個資源在Web之上都有自己的地址。連通性說的是:應該盡量避免設計孤立的資源,除了設計資源本身,還需要設計資源之間的關聯關系,並且通過超鏈接將資源關聯起來。無狀態、統一接口是REST的兩種架構約束,超文本驅動是REST的一個關鍵詞,在前面都已經解釋過,就不再贅述了。

從架構風格的抽象高度來看,常見的分布式應用架構風格有三種:

  • 分布式對象(Distributed Objects,簡稱DO)

架構實例有CORBA/RMI/EJB/DCOM/.NET Remoting等等

  • 遠程過程調用(Remote Procedure Call,簡稱RPC)

架構實例有SOAP/XML-RPC/Hessian/Flash AMF/DWR等等

  • 表述性狀態轉移(Representational State Transfer,簡稱REST)

架構實例有HTTP/WebDAV

DO和RPC這兩種架構風格在企業應用中非常普遍,而REST則是Web應用的架構風格,它們之間有非常大的差別。

REST與DO的差別在於:

  • REST支持抽象(即建模)的工具是資源,DO支持抽象的工具是對象。在不同的編程語言中,對象的定義有很大差別,所以DO風格的架構通常都是與某種編程語言綁定的。跨語言交互即使能實現,實現起來也會非常復雜。而REST中的資源,則完全中立於開發平臺和編程語言,可以使用任何編程語言來實現。

  • DO中沒有統一接口的概念。不同的API,接口設計風格可以完全不同。DO也不支持操作語義對於中間組件的可見性。

  • DO中沒有使用超文本,響應的內容中只包含對象本身。REST使用了超文本,可以實現更大粒度的交互,交互的效率比DO更高。

  • REST支持數據流和管道,DO不支持數據流和管道。

  • DO風格通常會帶來客戶端與服務器端的緊耦合。在三種架構風格之中,DO風格的耦合度是最大的,而REST的風格耦合度是最小的。REST松耦合的源泉來自於統一接口+超文本驅動。

REST與RPC的差別在於:

  • REST支持抽象的工具是資源,RPC支持抽象的工具是過程。REST風格的架構建模是以名詞為核心的,RPC風格的架構建模是以動詞為核心的。簡單類比一下,REST是面向對象編程,RPC則是面向過程編程。

  • RPC中沒有統一接口的概念。不同的API,接口設計風格可以完全不同。RPC也不支持操作語義對於中間組件的可見性。

  • RPC中沒有使用超文本,響應的內容中只包含消息本身。REST使用了超文本,可以實現更大粒度的交互,交互的效率比RPC更高。

  • REST支持數據流和管道,RPC不支持數據流和管道。

  • 因為使用了平臺中立的消息,RPC風格的耦合度比DO風格要小一些,但是RPC風格也常常會帶來客戶端與服務器端的緊耦合。支持統一接口+超文本驅動的REST風格,可以達到最小的耦合度。

比較了三種架構風格之間的差別之後,從面向實用的角度來看,REST架構風格可以為Web開發者帶來三方面的利益:

  • 簡單性

采用REST架構風格,對於開發、測試、運維人員來說,都會更簡單。可以充分利用大量HTTP服務器端和客戶端開發庫、Web功能測試/性能測試工具、HTTP緩存、HTTP代理服務器、防火墻。這些開發庫和基礎設施早已成為了日常用品,不需要什麽火箭科技(例如神奇昂貴的應用服務器、中間件)就能解決大多數可伸縮性方面的問題。

  • 可伸縮性

充分利用好通信鏈各個位置的HTTP緩存組件,可以帶來更好的可伸縮性。其實很多時候,在Web前端做性能優化,產生的效果不亞於僅僅在服務器端做性能優化,但是HTTP協議層面的緩存常常被一些資深的架構師完全忽略掉。

  • 松耦合

統一接口+超文本驅動,帶來了最大限度的松耦合。允許服務器端和客戶端程序在很大範圍內,相對獨立地進化。對於設計面向企業內網的API來說,松耦合並不是一個很重要的設計關註點。但是對於設計面向互聯網的API來說,松耦合變成了一個必選項,不僅在設計時應該關註,而且應該放在最優先位置。

有的讀者可能會問:“你說了這麽多,REST難道就沒有任何缺點了嗎?”當然不是,正如Fielding在博士論文中闡述的那樣,評價一種軟件架構的優劣,不能脫離開軟件的具體運行環境。永遠不存在適用於任何運行環境的、包治百病的銀彈式架構。筆者在前面強調過REST是一種為運行在互聯網環境中的Web應用量身定制的架構風格。REST在互聯網這個運行環境之中已經占據了統治地位,然而,在企業內網運行環境之中,REST還會面臨DO、RPC的巨大挑戰。特別是一些對實時性要求很高的應用,REST的表現不如DO和RPC。所以需要針對具體的運行環境來具體問題具體分析。但是,REST可以帶來的上述三方面的利益即使在開發企業應用時,仍然是非常有價值的。所以REST在企業應用開發,特別是在SOA架構的開發中,已經得到了越來越大的重視。本專欄將有一篇文章專門介紹REST在企業級應用中與SOA的結合。

到了這裏,“REST究竟是什麽”這個問題筆者就解答完了。本文開頭那些說法是否正確,筆者還是笑而不語,讀者此時應該已經有了自己的判斷。在接下來的REST系列文章中,我將會為讀者澄清一些關於HTTP協議和REST的常見誤解。

理解RESTful 架構