REST架構風格的由來

求知者發表於2016-12-06

筆者聽到REST也有快兩個年頭了,但是就筆者而言,身邊的同事,朋友談論它的很多,但總感覺說的有些欠缺,聽的人也感覺迷迷糊糊的。包括筆者的資深架構師同事也對REST的理解感覺不是那麼的地道,都停留在一個模稜兩可的程度。如果要細究REST,誰也說不出個一二,這讓筆者感覺很揪心。

本文只是筆者研究REST的一個總結,部分內容來源於由李錕、廖志剛、劉丹、楊光等對Feilding的論文的譯文,如果能對看到的朋友理解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

每種風格的詳細解釋見第六小節。

說明:本文參考了由李錕、廖志剛、劉丹、楊光等翻譯的<<架構風格與基於網路的軟體架構設計>>的部分內容。筆者很是佩服他們強烈的社會責任感,他們無私的翻譯了Feilding的博士論文給國人,再次向他們拜謝。

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

任選一種支付方式

REST架構風格的由來 REST架構風格的由來

相關文章