一 REST架構風格的由來
筆者聽到REST也有快兩個年頭了,但是就筆者而言,身邊的同僚,朋友談論它的很多,但總感覺說的有些欠缺,聽的人也感覺迷迷糊糊的。如果要細究REST,誰也說不出個一二,這讓筆者感覺很揪心。
1.建立REST的動機
作者開發 REST 的動機是為 Web 應該如何運轉建立一種架構模型,使之成為 Web 協定标準的指導架構。REST 被用來描述想要得到的 Web 架構,幫助識别出現有的問題,對各種替代方案進行比較,并且保證協定的擴充不會違反使 Web 成功的那些核心限制。
REST 的第一版開發于 1994 年 10 月和 1995 年 8 月之間,起初是作為作者編寫 HTTP/1.0規範和最初的HTTP/1.1 建議時,用來溝通各種 Web 概念的一種方法。它在随後的 5 年中以疊代的方式不斷改進,并且被應用于各種 Web 協定标準的修訂版和擴充之中。
2.明确定義
REST是一種架構風格,Roy Thomas Fielding 2000年在加州大學歐文分校的博士論文 《Architectural Styles and the Design of Network-based Software Architectures》中文譯為《架構風格與基于網絡的軟體架構設計》中對REST(Representational State Transfer,表述性狀态轉移)進行了詳細的描述。這篇論文定義了一個架構,緻力于通過架構風格來了解軟體架構,并且展示如何使用風格來指導基于網絡的應用的架構設計。
Fielding:Adobe首席科學家,Apache HTTP Server Project的聯合創始人,當過ASF的理事,HTTP規範的重要作者之一。
3.架構風格
它是一組協作的架構限制。這些限制限制了架構元素的角色和功能,以及在任何一個遵循該風格的架構中允許存在的元素之間的關系。限制往往是由在架構元素的某個方面使用軟體工程原則來驅動的。
4.軟體架構
何為軟體架構,該領域的研究者們從未達成過統一的定義,由于現代軟體系統的複雜性,系統實作被劃分為獨立的元件,這些元件通過互相通信來執行想要完成的任務。軟體架構研究如何以最佳方式劃分一個系統、如何辨別元件、元件之間如何通信、資訊如何溝通、組成系統的元素如何能夠獨立地進化,以及上述的所有東西如何能夠使用形式化的和非形式化的符号加以描述。
Fielding對軟體架構的定義為:一個軟體架構是一個軟體系統在其操作的某個階段的運作時元素的抽象。一個系統可能由很多層抽象和很多個操作階段組成,每個抽象和操作階段都有自己的軟體架構。
軟體架構由一些架構元素(元件、連接配接器和資料)的配置來定義,這些元素之間的關系受到限制,以獲得想要得到的一組架構屬性。
元件是軟體指令和内部狀态的一個抽象單元,通過其接口提供對于資料的轉換。
連接配接器是對于元件之間的通訊、協調或者合作進行仲裁的一種抽象機制(連接配接器的例子包括共享的表述、遠端過程調用、消息傳遞協定和資料流)。資料是元件通過一個連接配接器接收或發送的資訊元素。配置是在系統的運作期間元件、連接配接器和資料之間的架構關系的結構。
5.架構屬性
它包括了對元件、連接配接器和資料的選擇和排列所導緻的所有的屬性(包括了可以由系統獲得的功能屬性和非功能屬性,例如:進化的相對容易程度、元件的可重用性、效率、動态擴充能力,這些常常被稱作品質屬性)。
關鍵關注點架構屬性:性能(網絡性能、延遲、完成時間、網絡效率),可伸縮性,簡單性,可修改性(可進化性、可擴充性、可定制性、可配置性、可重用性),可見性, 可移植性, 可靠性。
REST強調元件互動的可伸縮性、接口的通用性、元件的獨立部署、以及用來減少互動延遲、增強安全性、封裝遺留系統的中間元件。
6.作者列出的架構風格
6.1.資料流風格(Data-flow Styles)
6.1.1 管道和過濾器(Pipe and Filter,PF)
每個元件(過濾器)從其輸入端讀取資料流并在其輸出端産生資料流,通常對輸入流應用一種轉換并增量地處理它們,以使輸出在輸入被完全處理完之前就能夠開始。這種風格也被稱作單路資料流網絡(one-way data flow network)。
6.1.2 統一管道和過濾器(Uniform Pipe and Filter,UPF)
該風格在 PF 風格的基礎上,添加了一個限制,即所有過濾器必須具有相同的接口。
6.2.複制風格(Replication Styles)
6.2.1 複制倉庫(Replicated Repository,RR)
基于複制倉庫風格的系統通過利用多個程序提供相同的服務,來改善資料的可通路性和服務的可伸縮性。這些分散的伺服器互動為用戶端制造出隻有一個集中的服務的“幻覺”。主要的例子包括諸如 XMS 這樣的分布式檔案系統和 CVS這樣的遠端版本控制系統。
6.2.2 緩存(Cache,$)
複制倉庫風格的一種變體是緩存風格,複制個别請求的結果,以便可以被後面的請求重用。
6.3.分層風格(Hierarchical Styles)
6.3.1 客戶-伺服器(Client-Server,CS)
該風格在基于網絡的應用的架構風格中最為常見。伺服器元件提供了一組服務,并監聽對這些服務的請求。用戶端元件通過一個連接配接器将請求發送到伺服器,希望執行一個服務。伺服器可以拒絕這個請求,也可以執行這個請求并将響應發送回用戶端。
6.3.2 分層系統(Layered System,LS)
一個分層系統是按照層次來組織的,每一層為在其之上的層提供服務,并且使用在其之下的層所提供的服務。盡管分層系統被看作一種“單純”的風格,但是它在基于網絡的
系統中的使用僅限于與客戶-伺服器風格相結合,形成分層-客戶-伺服器風格。分層系統的例子包括分層通信協定的處理,例如 TCP/IP 和OSI 協定棧。
6.3.3 分層-客戶-伺服器(LayeredClient-Server,LCS)
該風格在客戶-伺服器風格的基礎上添加了代理(proxy)元件和網關(gateway)元件。一個代理元件作為一個或多個用戶端元件的共享伺服器,它接收請求并進行可能的轉換後将其轉發給伺服器。一個網關元件在用戶端或代理看起來像是一個正常的伺服器,但是事實上它将請求進行可能的轉換後轉發給了它的“内部層”(inner- layer)伺服器。這些額外的中間元件添加了很多個層,用來為系統添加諸如負載均衡和安全性檢查這樣的功能。
6.3.4 客戶-無狀态-伺服器(Client-Stateless-Server,CSS)
該風格源自客戶-伺服器風格,并且添加了額外的限制:在伺服器元件之上不允許有會話狀态(session state)。從用戶端發到伺服器的每個請求必須包含了解請求所必需的全部資訊,不能利用任何儲存在伺服器上的上下文(context),會話狀态全部儲存在用戶端。
6.3.5 客戶-緩存-無狀态-伺服器(Client-Cache-Stateless-Server,C$SS)
該風格來源于客戶-無狀态-伺服器風格和緩存風格(通過添加緩存元件)。
6.3.6 分層-客戶-緩存-無狀态-伺服器(Layered-Client-Cache-StatelessServer,LC$SS)
該風格通過添加代理或網關元件,繼承了分層-客戶-伺服器風格和客戶-緩存-無狀态-伺服器風格。使用此風格的範例系統是 Internet 域名系統(DNS)。
6.3.7 遠端會話(Remote Session,RS)
該風格是客戶-伺服器風格的一種變體,它試圖使用戶端元件(而非伺服器元件)的複雜性最小化或者使得它們的可重用性最大化。每個用戶端在伺服器上啟動一個會話,然後調用伺服器的一系列服務,最後退出會話。應用狀态被完全儲存在伺服器上。這種風格通常在以下場合中使用:想要使用一個通用的用戶端(例如 TELNET)或者通過一個模仿通用用戶端的接口(例如 FTP )來通路遠端服務。
6.3.8 遠端資料通路(Remote Data Access,RDA)
該風格是客戶-伺服器風格的一種變體,它将應用狀态分布在用戶端和伺服器上。用戶端以一種标準的格式發送一個資料庫查詢(例如 SQL)請求到伺服器,伺服器配置設定一個工作空間并執行這個查詢,這可能會導緻一個巨大的結果集。用戶端能夠在結果集上進行進一步操作(例如表連接配接)或者每次擷取結果的一部分。用戶端必須了解服務的資料結構,以便建造依賴于該結構的查詢。
6.4.移動代碼風格(Mobile Code Styles)
6.4.1 虛拟機(Virtual Machine,VM)
所有移動代碼風格的基礎是虛拟機(或解釋器)風格。代碼必須以某種方式來執行,首選的方式是在一個滿足了安全性和可靠性關注點的受控環境中執行,而這正是虛拟機風格所提供的。
6.4.2 遠端求值(Remote Evaluation,REV)
該風格來源于客戶-伺服器風格和虛拟機風格,一個用戶端元件必須要知道如何來執行一個服務,但缺少執行此服務所必需的資源(CPU 周期、資料源等等),這些資源恰好位于一個遠端站點上。是以,用戶端将如何執行服務的代碼發送給遠端站點上的一個伺服器元件,伺服器元件使用可用的資源來執行代碼,然後将執行結果發送回用戶端。
6.4.3 按需代碼(Code on Demand,COD)
在該風格中,一個用戶端元件知道如何通路一組資源,但不知道如何處理它們。它向一個遠端伺服器發送對于如何處理資源的代碼的請求,接收這些代碼,然後在本地執行這些代碼。
6.4.4 分層-按需代碼-客戶-緩存-無狀态-伺服器(Layered-Code-on-DemandClient-Cache-Stateless-Server,LCODC$SS)
将按需代碼風格添加到上面讨論過的分層-客戶-緩存-無狀态-伺服器風格上。因為代碼被看作不過是另一種資料元素,是以這并不會妨礙LC$SS 風格的優點。
6.4.5 移動代理(Mobile Agent,MA)
在該風格中,一個完整的計算元件,與它的狀态、必需的代碼、執行任務所需的資料一起被移動到遠端站點。該風格可以看作來源于遠端求值風格和按需代碼風格,因為移動性是同時以這兩種方式工作的。
6.5.點對點風格(Peer-to-Peer Styles)
6.5.1 基于事件的內建(Event-based Integration,EBI)
該風格不是直接調用另一個元件,而是一個元件能夠釋出(或廣播)一個或者多個事件。在事件釋出後,系統中的其他元件能夠注冊對于某些事件類型的興趣,由系統本身來調用所有已注冊的元件。
6.5.2 C2
C2 架構風格直接支援大粒度的重用,并且通過加強底層獨立性,支援系統元件的靈活組合。它通過将基于事件的內建風格和分層-客戶-伺服器風格相結合來達到這些目标。
6.5.3 分布式對象(Distributed Objects,DO)
該風格将系統組織為結對進行互動的元件的集合。一個對象是一個實體,這個實體封裝了一些私有的狀态資訊或資料、操作資料的一組相關的操作或過程、以及一個可能存在的控制線程,這種封裝使得它們能夠被整體地看作單個的單元。
6.5.4 被代理的分布式對象(Brokered Distributed Objects,BDO)
該風格引入了名稱解析元件——其目的是将該元件接收到的用戶端請求中一個通用的服務名稱解析為一個能夠滿足該請求的對象的特定名稱,并使用這個特定名稱來答複用戶端。
7.REST所繼承的風格限制

每種風格的詳細解釋見第六小節。
二 REST架構風格的架構元素
表述性狀态轉移(REST)風格是對分布式超媒體系統中的架構元素的一種抽象。REST忽略了元件實作和協定文法的細節,以便聚焦于以下幾個方面:元件的角色、元件之間的互動之上的限制、元件對重要資料元素的解釋。REST包括了一組對于定義 Web 架構基礎的組 件、連接配接器和資料的基本限制,是以它代表了基于網絡的應用的行為的本質。
REST提供了一組架構限制,當作為一個整體來應用時,強調元件互動的可伸縮性、接口的通用性、 元件的獨立部署、以及用來減少互動延遲、增強安全性、封裝遺留系統的中間元件。
如下為REST的架構元素。
1.資料元素(Data Elements)
1.1資源和資源辨別符(Resources and Resource Identifiers)
REST對于資訊的核心抽象是資源。任何能夠被命名的資訊都能夠作為一個資源:一份文檔或一張圖檔、一個與時間相關的服務(例如,“北京今日的天氣”)、一個其他資源的集合、一個非虛拟的對象(例如,人)等等。REST使用一個資源辨別符來辨別元件之間互動所涉及到的特定資源。
1.2表述(Representations)
REST元件通過以下方式在一個資源上執行動作:使用一個表述來捕獲資源的目前的或預期的狀态、在元件之間傳遞該表述。一個表述是一個位元組序列,以及描述這些位元組的表述中繼資料。表述的其他常用但不夠精确的名稱包括:文檔、檔案、HTTP 消息實體、執行個體或變量。表述的資料格式被稱為一種媒體類型。
2.連接配接器(Connectors)
REST使用多種不同的連接配接器類型來對通路資源和轉移資源表述的活動進行封裝。連接配接器代表了一個元件通信的抽象接口,通過提供清晰的關注點分離、 并且隐藏資源的底層實作和通信機制,進而改善了架構的簡單性。接口的通用性也使得元件 的可替換性成為了可能:如果使用者對系統的通路僅僅是通過一個抽象的接口,那麼接口的實作就能夠被替換,而不會對使用者産生影響。由于元件的網絡通信是由一個連接配接器來管理的,是以在多個互動之間能夠共享資訊,以便提高效率和響應能力。
3.元件(Components)
REST 元件根據它們在整個的應用動作中的角色來進行分類。