|
任何概念從產生到付諸實施似乎都要經歷一個同樣冗長的過程,從被提出,誤解,詮釋,再認識,到應用,好像沒有幾個技術觀點能夠跳過這些,現在的RESTful架構似乎也正處在這個過程的中段。互聯網上關于REST的介紹性文章可謂鋪天蓋地,園子里的帖子也有不少,但是其中大多數都是一個對REST這一概念的精辟概述,比較流行的樣式是一句話總結或將其特性列表,這樣的總結對于讀者來說的確提供了較大的便利,它們容易被人記住,也的確反映了從最終使用者角度來看REST最為顯著的幾個特性。但是它們同時也很容易讓讀者覺得了解了這些就幾乎了解了REST的全部,而不會繼續探究細節,也許這就導致了許多朋友對REST理解較為片面的原因吧。比如我看到有些朋友認為操作HTTP原語就是REST,有些人認為只要在URL上花心思了就是REST,其實他們的看法都表現了基于HTTP和URL的REST架構風格在實現層面的重要組成部分,但以其來定義REST本身未免過于草率。于是,我便有了寫這系列隨筆的想法。我并不是為了向大家介紹REST,而是想和大家分享下自己對這個架構風格的理解,如果能夠以此解答大家對于REST的一些困惑的話,那是我的榮幸。
相信任何關于REST的介紹性文章都會提到Roy T. Fielding博士在2000年發表的一篇論文,然而對這篇文章本身的關注度似乎比對它的引用要少的多。這篇論文本身并不僅僅是為提出REST而作的,而是介紹了一種以架構風格為指導的,針對網絡應用架構設計的方法論,而REST是被作為這種方法論的應用推導出的一種適應分布式超媒體系統的架構風格。文中作者將架構風格定義為:
一組協作的架構約束,這些約束限制了架構元素的角色和功能,以及在任何一個遵循該風格的架構中允許存在的元素之間的關系。
這里的“架構約束”指的是對系統在運行時表現出的某組屬性的需求。舉例來說,如果期望“系統具有可伸縮性”(系統屬性),那么在Web系統中對應的架構約束之一就可以是“在服務器上不保留會話狀態”。一般來說,基于Web的系統所關注的屬性主要有性能(Performance),可伸縮性(Scalability),可擴展性(Extensibility),可移植性(Portability)和可靠性(Reliability)等,而把與其相對應的相關約束進行不同的組合便形成了各種架構風格。比如最為常見的Client-Server風格,就是與可伸縮性和簡單性等對應的約束集合。Fielding博士在論文中對基于架構風格的分類有詳細論述,這里就不多做解釋了?;谇懊鎸軜嬶L格的定義,Fielding博士從識別互聯網應用需求開始一步一步推導出了早期互聯網的架構約束,并在此基礎上添加現代分布式超媒體系統所需要的屬性,從而獲得一個全新的架構風格,它表現了現代互聯網背后的運轉模型,并滿足分布式超媒體系統提出的約束條件,這便是表述型狀態轉移(REpresentational State Transfer, REST)架構風格產生的過程。
這個過程意味著兩個事實,首先,由于REST是為了獲得某種系統屬性的架構約束集合,所以它不與任何具體實現相關聯。任何能夠滿足這組特定約束的實現都是可以被稱為REST式的架構。雖然這一結論已經有口皆碑,許多帖子或介紹性文章也都會有類似于“...REST首先只是一種架構樣式,不是一種標準...”這樣的話,然而在我自己的學習過程中,這些簡要的概述卻著實在理解上給我帶來了一些麻煩。曾經困擾過我的問題有“架構樣式與標準有何區別”,“為什么REST算是一種架構樣式”,“CS也算是一種架構樣式那么怎樣區分將其與REST區分開來”等等,而在了解了REST的推導過程后這些問題便迎刃而解了。
另外,縱觀REST的推導過程,可以發現這一架構風格與互聯網緊密結合,我不是說在使用的技術上,而是在期望實現的架構屬性方面,REST是基于互聯網所表現的屬性之上的。屬性代表著系統運行時表現出的功能,也就是說REST風格架構的適用場合必然與互聯網密切相關。互聯網創始人Tim Berners Lee說過這樣的話:“The web is the universe of globally accessible information”,它點出了互聯網用于分享資源的屬性。那么我們能不能以此推論與之具有相似架構約束的REST風格也是面向資源的呢?答案是肯定的,而上面簡短的推導過程也正是“REST是面向資源的(Resource-Oriented)”這一論述的理論依據。
資源作為REST架構風格的一個核心元素就其本身來說是沒有多大價值的,它們的價值來源于被人發現和使用,以及與其他資源間的交互。為了實現這一屬性,REST引入了稱為資源標識符(Resource Identifier)的架構元素,它們表現為一種查找和獲取資源的方法,使得資源具有可尋址性(addressability),在互聯網(作為REST架構的一個實現)中資源標識符就是URL了。接下來被發現的資源必須通過一種方式被使用者認識和使用,它們需要向客戶端“介紹”自己,有時候為了迎合客戶端的口味還需要以多種方式去“展現”自己,或展現“過去的自己”,這種展現在REST中便是資源的表述(Representation)。每一個資源都是其表述的來源(source),一個資源可以有多種類型的表述。舉例來說,“SNOOPY”這一資源可以被表述為一份描述一只狗的XML或是一幅漫畫,而無論它被描繪成哪種形式,其對于使用該資源的客戶來說都是長篇漫畫Peanuts中的主角。從概念上來看,這和語義網(Semantic Web)的構想是相似的,他們都有通過“一組正式的、被明確定義的詞匯,來記錄和描繪一個普遍認知”的需求。前面提到資源可能會需要展現“過去的自己”,這可以被理解資源對其自身在某一個特定狀態(State)下的表述。舉例來說,上周我從圖書館借回來了一本名為《Everyday Italian》的書,由于發現書中部分內容與我了解的不一致,我添加了一些批注。于是乎接下來所有這本書最新版本的請求都變成了由我添加過批注的這個版本(假設該書可供借閱的數量只有一本,而備份版本存于書庫,需要提交申請),也就是說這個資源的狀態(Resource state)被“添加批注”這個動作改變,而對該書最新版本的請求意味著對資源當前狀態的表述的請求。我的批注惹惱了作者的一些FANS,于是有許多對備份版本的請求提交到了圖書館,類似于這樣“請給我該書2009年6月12日以前的最新版本”。圖書館管理員在收到這樣的請求后首先對我這樣的讀者發了句牢騷,然后根據索引號去書庫查找備份版本。在這個場景中,最終用戶得到的表述資源狀態發生了改變,從最新版本變為了某一特定時間的歷史版本,而資源本身并未改變(這里我將該書作為一個資源看待)。這里客戶端獲得的始終是資源的表述狀態,對資源狀態的表述在請求響應過程中從服務端被轉移(Transfer)至了客戶端,而在被轉移的狀態中又包含著將請求方引導至其他狀態的連接(Hyperlinks)。資源,表述,狀態,轉移這幾個元素便成為了表述型狀態轉移(REpresentational State Transfer)這一架構風格的基本要素。
以上從架構元素角度定義了REST風格,而在資源的連接與交互方面,REST也提出了為實現系統可伸縮性、組件可替換性以及性能優化等屬性的要求。這些約束中統一接口,無應用狀態等是最為關鍵的幾點,對他們的論述網絡上也比比皆是,比如發布于InfoQ上的A Brief Introduction to REST就很詳細地解釋了使用標準化方法與資源進行交互和無狀態溝通的含義和原因,這里就不再贅述了。另外,我在過去的一篇帖子里也簡單談了一些自己對無狀態這一概念的理解,有興趣的朋友可以參考一下,而對于基于HTTP和URL的REST中,統一接口和無應用狀態的實際表現形式,例如對HTTP原語的使用等,我會在接下來的幾篇隨筆里與大家分享我的認識。
REST源于互聯網也用于互聯網,這也就意味著REST對其適用場合有著默認的假設。由于REST將互聯網作為一個開放的發布媒體,而不是一個通信媒介,所以REST期望其應用場景是一個為了通過網絡公開并分享某些資源的分布式超媒體系統,這些資源可以是靜態文本或圖片,也可以是系統處理數據的能力。這也就意味著REST其實并不適用于一些業務邏輯復雜的企業應用,此類應用通常不希望任何與業務過程不相關的實體分享信息,而它們在其他一些方面的特殊要求,如服務器端對客戶端應用狀態的保留和復雜的安全基礎設施等,都是與REST架構風格中某些約束相沖突或REST沒有涉及的。所以硬將REST風格套用到這樣的企業應用上,我覺得著實有點勉為其難。REST中的組件復合模式也同樣說明了這點??紤]下現在的一些信息門戶網站,許多信息的展現都是通過從多個來源獲取與相關的數據或功能來完善的,這也就是我們常說的mashup,而mashup便是REST所期望的信息(資源)復合模式。在這一形式中,資源與資源通過超鏈接連接成一個復合的表述,而不受某個高層工作流或既定業務流程的控制。與之相對的,企業應用中的數據或功能通常是被作為某個業務流程中的一個組成部分被復合到一起的,這一流程指導著數據或功能的使用時機以及下一步的交互對象。在這個模式下服務器端維護狀態信息幾乎成為了必然,當然可以將狀態信息存于客戶端,并通過將其包含于每個請求發送至服務端的方式來實現REST式的架構,但是這樣做沖銷了REST的簡潔性的優勢,也可能增加網絡傳輸的負擔。
以上便是我對于REST架構風格的一些個人體會,從解釋REST的推導過程到其適用場合的假設,希望這些理論味道有點濃的文字能夠給大家帶來一些小小收獲。接下來的幾篇隨筆里我會主要和大家聊一下自己基于HTTP和URL的REST架構中一些元素的理解,討論一些我在學習過程中看到的爭論,發表一下自己的看法。
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。