REST本身是一個高度抽象化的架構(gòu)風格,因而總是很難對它有一個比較深入且印象深刻的理解。寫這篇文章的目的,是自己對學(xué)習(xí)REST的一個總結(jié)毅糟,也希望可以通過這篇文章,能夠讓讀者真正的理解REST澜公。
本文主要內(nèi)容
- 什么是REST
- REST概念
- REST的由來
- REST的理解
- REST的架構(gòu)約束條件
- 客戶/服務(wù)器模型
- 無狀態(tài)
- 緩存
- 統(tǒng)一接口
- 分層系統(tǒng)
- 小結(jié)
- 總結(jié)
什么是REST
REST的概念
先來看看百度對REST的定義:
REST即表述性狀態(tài)傳遞(英文:Representational State Transfer留特,簡稱REST)是Roy Fielding博士在2000年他的博士論文中提出來的一種軟件架構(gòu)風格。它是一種針對網(wǎng)絡(luò)應(yīng)用的設(shè)計和開發(fā)方式玛瘸,可以降低開發(fā)的復(fù)雜性,提高系統(tǒng)的可伸縮性苟蹈。
- 我們更多的將REST稱為表述性狀態(tài)轉(zhuǎn)移糊渊。
- 所謂的表述性狀態(tài)轉(zhuǎn)移,是對什么的表述慧脱?——資源
- REST省略了主語Resource(資源)渺绒,全稱是 Resource Representational State Transfer,即資源表述性狀態(tài)轉(zhuǎn)移菱鸥。通俗來講就是:資源在網(wǎng)絡(luò)中以某種表現(xiàn)形式進行狀態(tài)轉(zhuǎn)移宗兼。
- 如果一個架構(gòu)符合REST原則,就稱它為RESTful架構(gòu)氮采。
在對REST更深一步的解釋之前殷绍,我們先來看看REST的由來,而這對于REST的理解至關(guān)重要鹊漠。
REST的由來
首先簡單了解一下作者——Roy Thomas Fielding
- HTTP/1.0協(xié)議專家組成員
- HTTP/1.1協(xié)議專家組負責人
- Apache HTTP服務(wù)器的核心開發(fā)者
- Apache軟件基金會合作創(chuàng)始人
一張圖說明REST的由來:
好吧主到,這是一張很簡陋的圖茶行,不過用來解釋REST的由來足夠了。
故事得從遠古時期的HTTP/1.0協(xié)議說起登钥,隨著web技術(shù)的發(fā)展畔师,沿用多年且面向靜態(tài)文檔的HTTP/1.0協(xié)議無法滿足web應(yīng)用的開發(fā)需求,作為HTTP/1.0協(xié)議專家組成員之一的Roy Fielding脫穎而出牧牢,成為了HTTP/1.1協(xié)議專家組的負責人看锉,負責統(tǒng)籌制定新版本的協(xié)議。
Roy Fielding和他的同事們在制定HTTP/1.1協(xié)議的過程中塔鳍,從技術(shù)架構(gòu)層面對web之所以能獲得巨大成功做了一番深入的研究和總結(jié)伯铣,之后將這些總結(jié)納入到一套理論框架之中,并利用這套理論框架中的指導(dǎo)原則献幔,指導(dǎo)HTTP/1.1協(xié)議的設(shè)計方向懂傀。經(jīng)過三年的修訂,HTTP/1.1協(xié)議于1999年6月正式成為規(guī)范蜡感。HTTP/1.1協(xié)議設(shè)計取得了極大的成功蹬蚁,在發(fā)布之后的十年里,都沒有多少人認為有修訂的必要郑兴。
Fielding在完成HTTP/1.1協(xié)議的設(shè)計工作之后犀斋,回到了加州大學(xué)歐文分校繼續(xù)攻讀自己的博士學(xué)位。第二年(2000年)在他的博士學(xué)位論文Architectural Styles and the Design of Network-based Software Architectures中(中文版名為《架構(gòu)風格與基于網(wǎng)絡(luò)的軟件架構(gòu)設(shè)計》)情连,F(xiàn)ielding更為系統(tǒng)叽粹、嚴謹?shù)仃U述了這套理論框架,并且使用這套理論框架推導(dǎo)出了一種新的架構(gòu)風格却舀,并且為這種架構(gòu)風格取了一個令人輕松愉快的名字“REST”——Representational State Transfer(表述性狀態(tài)轉(zhuǎn)移)的縮寫虫几。
這便是REST的由來,可以看出挽拔,REST架構(gòu)風格辆脸,是通過推導(dǎo)web的技術(shù)架構(gòu)因素層面而總結(jié)出來的,總結(jié)出來的理論框架被用來指導(dǎo)HTTP/1.1協(xié)議的設(shè)計方向螃诅。那么我們可以這樣理解啡氢,REST是Web自身的架構(gòu)風格,REST是HTTP/1.1協(xié)議等Web規(guī)范的設(shè)計指導(dǎo)原則术裸,HTTP/1.1協(xié)議正是為實現(xiàn)REST風格的架構(gòu)而設(shè)計的倘是。
REST的理解
什么是web
從REST的來源中我們發(fā)現(xiàn),要想深刻理解REST袭艺,首先得了解web搀崭。
先來看一些web的相關(guān)知識:
百度百科
web(World Wide Web)即全球廣域網(wǎng),也稱為萬維網(wǎng)猾编,它是一種基于超文本和HTTP的门坷、全球性的宣鄙、動態(tài)交互的、跨平臺的分布式圖形信息系統(tǒng)默蚌。是建立在Internet上的一種網(wǎng)絡(luò)服務(wù)冻晤,為瀏覽者在Internet上查找和瀏覽信息提供了圖形化的、易于訪問的直觀界面绸吸,其中的文檔及超級鏈接將Internet上的信息節(jié)點組織成一個互為關(guān)聯(lián)的網(wǎng)狀結(jié)構(gòu)鼻弧。
維基百科
萬維網(wǎng)(英語:World Wide Web),亦作“WWW”锦茁、“Web”攘轩,是一個由許多互相鏈接的超文本組成的系統(tǒng),通過互聯(lián)網(wǎng)訪問码俩。
萬維網(wǎng)并不等同互聯(lián)網(wǎng)度帮,萬維網(wǎng)只是互聯(lián)網(wǎng)所能提供的服務(wù)其中之一,是靠著互聯(lián)網(wǎng)運行的一項服務(wù)稿存。
互聯(lián)網(wǎng)和萬維網(wǎng)用語經(jīng)常被使用且沒有太多區(qū)別笨篷。然而,兩者是不一樣的瓣履÷食幔互聯(lián)網(wǎng)是電腦網(wǎng)絡(luò)互相連接的全球系統(tǒng)。相較之下袖迎,萬維網(wǎng)是全球收集的文件和其他資源冕臭,通過超鏈接和URIs連接。萬維網(wǎng)資源通常使用HTTP訪問燕锥,這是互聯(lián)網(wǎng)通信協(xié)議的一種辜贵。
萬維網(wǎng)的核心部分是由三個標準構(gòu)成的:
- 統(tǒng)一資源標識符(URI),這是一個統(tǒng)一的為資源定位的系統(tǒng)归形。
- 超文本傳送協(xié)議(HTTP)念颈,它負責規(guī)定客戶端和服務(wù)器怎樣互相交流。
- 超文本標記語言(HTML)连霉,作用是定義超文本文檔的結(jié)構(gòu)和格式。
總結(jié)來說嗡靡,web是一個由許多相互鏈接的超文本組成的系統(tǒng)跺撼,它使用URI來定位系統(tǒng)中的每一個資源,并通過HTTP協(xié)議進行數(shù)據(jù)的交互讨彼。
更抽象的說歉井,Web是一個分布式信息系統(tǒng),為超文本文件和其他對象(資源)提供訪問接口和訪問機制哈误。
理解了什么是web哩至,我們便可以更好地理解什么是REST了躏嚎。作為web自身的架構(gòu)風格,我們直接給出結(jié)論:REST本質(zhì)上是一種分布式超媒體系統(tǒng)的應(yīng)用層解決方案菩貌,它為資源互通和資源管理的分離提出了一系列架構(gòu)約束和原則卢佣,得到一個功能強、性能好箭阶、適宜通信的以網(wǎng)絡(luò)為基礎(chǔ)的應(yīng)用軟件架構(gòu)虚茶。
這個結(jié)論依然很難理解,但我們需要對此有一個概念了解仇参。接下來我們會對REST進行更為詳細的介紹嘹叫。
REST詞組
要理解REST,首先需要理解(Resource)Representational State Transfer這個詞組诈乒。
資源(Resource)
REST對于信息的核心抽象是資源罩扇。任何能被命名的信息都能作為一個資源:一份文檔、一個與時間相關(guān)的服務(wù)(例如怕磨,“洛杉磯今日的天氣”)喂饥,一個其他資源的集合、一個非虛擬的對象(例如癌压,人)等等仰泻。
換句話說,可以作為創(chuàng)作者的超文本引用的目標(the target of an author's hypertext reference)的任何概念都必須符合資源的定義滩届。資源是到一組實體的概念性映射(a conceptual mapping)集侯,而不是在任何特定時刻與該映射相關(guān)聯(lián)的實體本身。
更精確地說帜消,資源R是一個隨時間變化的成員函數(shù)該函數(shù)根據(jù)時間t將資源映射到一個實體或值的集合棠枉,集合中的值可能是資源表述(resource representations)和/或資源標識符(resource identifiers)(兩者是等價的)。
對于一個資源來說泡挺,唯一必須靜態(tài)的是映射的語義辈讶,因為語義才是區(qū)別資源的關(guān)鍵。
正是資源的這個抽象定義娄猫,使得Web架構(gòu)的核心功能得以實現(xiàn)贱除。首先,它包含了很多信息的來源媳溺,并沒有人為地通過類型或?qū)崿F(xiàn)對它們加以區(qū)分月幌,從而實現(xiàn)了通用性。其次悬蔽,它允許引用到表述的延遲綁定扯躺,從而支持基于請求的性質(zhì)來進行內(nèi)容協(xié)商。最后,它允許創(chuàng)作者引用一個概念而不是引用此概念的某個單獨的表述录语,從而使得當表述改變時無需修改所有的現(xiàn)有鏈接(假設(shè)創(chuàng)作者使用了正確地標識符)
如何來理解“對于一個資源來說倍啥,唯一必須靜態(tài)的是映射的語義,因為語義才是區(qū)別資源的關(guān)鍵”這句話呢澎埠?舉一個簡單的例子來說明一下:
“一個APP的當前版本”是一個資源虽缕,而“一個APP的最穩(wěn)定版本”也是一個資源,盡管這兩個資源在某個時刻上可能會映射到相同的值失暂,但它們是是截然不同的彼宠,且兩個資源能夠被單獨地標識和引用。
資源標識符
REST使用資源標識符來表示組件之間交互所涉及的特定資源弟塞。REST連接器提供了訪問和操作資源的值集合的一個通用的接口凭峡,而無須關(guān)心其成員函數(shù)(membership function)是如何定義的,或者處理請求的軟件是何種類型决记。由命名權(quán)威(naming authority)來為資源分配資源標識符摧冀,使得引用資源成為可能,映射的語義有效性也由同樣的命名權(quán)威來負責維護(例如系宫,確保成員函數(shù)不會改變)索昂。
傳統(tǒng)的超文本系統(tǒng)通常只在一個封閉的或局部的環(huán)境中運行,它們使用隨信息的變化而改變的唯一節(jié)點或文檔標識符扩借,并依賴鏈接服務(wù)器(link server)以獨立于內(nèi)容的方式來維護引用椒惨。因為集中式的鏈接服務(wù)器完全無法滿足Web的超大規(guī)模和跨越多個組織領(lǐng)域的需求,所以REST采用了其他的方式——以來資源的創(chuàng)作者來選擇最符合被標識的概念本質(zhì)的資源標識符潮罪。
資源標識符為訪問和操作資源的值集合提供了一個通用的接口康谆。換句話說,我們抽象出來的資源都應(yīng)該是可標識的嫉到,都應(yīng)該擁有一個明顯的ID——在Web中沃暗,代表ID的統(tǒng)一概念是:URI(統(tǒng)一資源標識符)。URI構(gòu)成了一個全局命名空間何恶,使用URI標識關(guān)鍵資源意味著這些資源獲得了一個唯一孽锥、全局的ID。
舉個簡單的例子:如果在一個類似于Amazon.com的在線商城中细层,沒有用唯一的ID(一個URI)標識它的每一件商品惜辑,可想而知這將是多么可怕的業(yè)務(wù)決策。
表述(Representations)
資源的表述是一段對于資源在某個特定時刻的狀態(tài)的描述疫赎。
資源在外界的具體呈現(xiàn)盛撑,可以有多種表述(或稱為表現(xiàn)、表示)形式虚缎,在客戶端和服務(wù)端之間傳送的也是資源的表述,而不是資源本身。 例如文本資源可以采用html实牡、xml陌僵、json等格式,圖片可以使用PNG或JPG展現(xiàn)出來创坞。 資源的表述包括數(shù)據(jù)和描述數(shù)據(jù)的元數(shù)據(jù)碗短,例如,HTTP頭“Content-Type” 就是這樣一個元數(shù)據(jù)屬性题涨。
更確切的說:
REST組件使用表述來捕獲某個資源的當前狀態(tài)或預(yù)期狀態(tài)偎谁,隨后在組件之間移交該表述,同過這種方式在資源上執(zhí)行各種動作(perform actions on a resource)纲堵。表述(representation)有一個字節(jié)序列和描述這些字節(jié)的表述元數(shù)據(jù)(representation metadata)構(gòu)成巡雨。表述的其他常用但不精確的名稱包括:文檔、文件席函、HTTP消息實體铐望、實例或變量。
表述由數(shù)據(jù)茂附、描述數(shù)據(jù)的元數(shù)據(jù)正蛙、以及(有時候存在的)描述元數(shù)據(jù)的元數(shù)據(jù)組成(通常用來驗證消息的完整性)。
表述的數(shù)據(jù)格式被稱為媒體類型(media type)营曼。
簡單總結(jié)一下:
- 資源總是以某種表述為載體顯示的,即序列化的信息
- 資源的表述是REST架構(gòu)的表現(xiàn)層
- 資源可以有多重表述
狀態(tài)轉(zhuǎn)移
狀態(tài)轉(zhuǎn)移:在客戶端和服務(wù)器端之間轉(zhuǎn)移(transfer)代表資源狀態(tài)的表述。通過轉(zhuǎn)移和操作資源的表述蒙揣,來間接實現(xiàn)操作資源的目的庆亡。
訪問一個網(wǎng)站,就代表了客戶端和服務(wù)器的一個互動過程蒜危。在這個過程中虱痕,勢必涉及到數(shù)據(jù)和狀態(tài)的變化。
互聯(lián)網(wǎng)通信協(xié)議HTTP協(xié)議辐赞,是一個無狀態(tài)協(xié)議部翘。這意味著,所有的資源狀態(tài)都保存在服務(wù)器端响委。因此新思,如果客戶端想要操作服務(wù)器中的資源,必須通過某種手段赘风,讓服務(wù)器端的資源發(fā)生"狀態(tài)轉(zhuǎn)移"(State Transfer)夹囚。而這種轉(zhuǎn)化是建立在表述之上的,所以就是"表述性狀態(tài)轉(zhuǎn)移"邀窃。
客戶端使用的手段荸哟,在web中就是HTTP協(xié)議假哎。具體來說,就是HTTP協(xié)議里面鞍历,四個表示操作方式的動詞:GET舵抹、POST、PUT劣砍、DELETE惧蛹。它們分別對應(yīng)四種基本操作:
- GET——獲取資源
- POST——新建資源(也可以用于更新資源)
- PUT——更新資源
- DELETE——刪除資源
小結(jié)
Resource Representational State Transfer,資源表述性狀態(tài)轉(zhuǎn)移刑枝,即就是:根據(jù)數(shù)據(jù)抽象出來的資源香嗓,以某種表現(xiàn)形式,通過某種手段装畅,在網(wǎng)絡(luò)中發(fā)生狀態(tài)轉(zhuǎn)移靠娱,以此來間接實現(xiàn)操作資源的目的。表述性狀態(tài)轉(zhuǎn)移(REST)架構(gòu)風格是對分布式超媒體系統(tǒng)中的架構(gòu)元素的一種抽象洁灵。
在web中饱岸,具體而言:
- 每一個URI代表一種資源;
- 客戶端和服務(wù)器之間徽千,傳遞這種資源的某種表現(xiàn)層苫费;
- 客戶端通過四個HTTP動詞,對服務(wù)器端資源進行操作双抽,實現(xiàn)"表現(xiàn)層狀態(tài)轉(zhuǎn)化"百框。
我們再來換一個角度,以搭建系統(tǒng)的角色來思考這個問題:
在web中牍汹,為了獲取我們需要的分布在不同地域的超媒體資源铐维,我們該如何設(shè)計這個系統(tǒng)?顯然慎菲,web中有著大量的嫁蛇,分布在不同地方的各種類型的資源。我們需要提供的是一個大型分布式超媒體系統(tǒng)的應(yīng)用層解決方案露该。
首先我們需要為所需的數(shù)據(jù)設(shè)定唯一標識睬棚,因此我們將數(shù)據(jù)進行抽象為資源,并使用統(tǒng)一資源標識符(URI)為每個資源設(shè)定ID解幼,這樣我們就有辦法來操作每個資源抑党。
那么該如何操作資源呢?換句話說撵摆,當我們看到一個URI并將它輸入到瀏覽器中是底靠,為何瀏覽器知道該怎樣處理這個URI?事實上特铝,瀏覽器知道如何去處理URI的原因在于:所有的資源都支持同樣的接口(URI)暑中,支持一套同樣的方法(HTTP動詞)壹瘟。這樣,當我們自己按照這種方式來定義我們自己的資源時鳄逾,web中的其他人便可以輕松的獲取這些資源俐筋。
獲取資源時,我們可能需要不同的呈現(xiàn)方式或是需求严衬,因此我們需要對資源進行表述,使其表現(xiàn)為我們需要的形式笆呆。
從分布式系統(tǒng)的角度來看REST请琳,我們發(fā)現(xiàn)以資源為核心的REST確實提供了一種解決大型分布式資源系統(tǒng)的解決方案,而web的成功也確實驗證了這套理論的正確性赠幕。
REST的架構(gòu)約束條件
REST作為一種組織web服務(wù)的架構(gòu)風格俄精,提出了一系列架構(gòu)級約束。如果一個系統(tǒng)滿足這些約束榕堰,那該系統(tǒng)就被稱為是RESTful的竖慧。接下來,我們會逐條說明REST的五條必要約束逆屡。
客戶/服務(wù)器模型
通信只能由客戶端單方面發(fā)起圾旨,表現(xiàn)為請求-響應(yīng)的形式。
客戶-服務(wù)器約束背后的原則是分離關(guān)注點魏蔗。通過分離用戶界面和數(shù)據(jù)存儲這兩個關(guān)注點砍的,我們改善了用戶界面跨多個平臺的可移植性;同時通過簡化服務(wù)器組件莺治,改善了系統(tǒng)的可伸縮性廓鞠。然而,對于Web來說谣旁,最重要的是這種關(guān)注點的分離使得組件可獨立地進化床佳,從而支持多個組織領(lǐng)域的互聯(lián)網(wǎng)規(guī)則的需求。
無狀態(tài)
我們接下來在為客戶-服務(wù)器交互添加一個架構(gòu)約束:通信必須在本質(zhì)上是無狀態(tài)的榄审,從客戶到服務(wù)器的每個請求都必須包含理解該請求所必需的所有信息砌们,不能利用任何存儲在服務(wù)器端的上下文,會話狀態(tài)因此要全部保存在客戶端瘟判。
前面我們分析REST詞組時怨绣,提到了資源的狀態(tài)轉(zhuǎn)移,而在這里拷获,REST約束中又包含了無狀態(tài)通信原則篮撑,看起來仿佛是矛盾了:既然“無狀態(tài)”,又怎么能說“狀態(tài)轉(zhuǎn)移”呢匆瓜?
其實赢笨,這里說的無狀態(tài)通信原則未蝌,并不是說客戶端應(yīng)用不能有狀態(tài),而是指服務(wù)端不應(yīng)該保存客戶端狀態(tài)茧妒。
應(yīng)用狀態(tài)與資源狀態(tài)
狀態(tài)應(yīng)該區(qū)分應(yīng)用狀態(tài)和資源狀態(tài)萧吠,客戶端負責維護應(yīng)用狀態(tài),而服務(wù)端維護資源狀態(tài)桐筏。 客戶端與服務(wù)端的交互必須是無狀態(tài)的纸型,并在每一次請求中包含處理該請求所需的一切信息。服務(wù)端不需要在請求間保留應(yīng)用狀態(tài)梅忌,只有在接受到實際請求的時候狰腌,服務(wù)端才會關(guān)注應(yīng)用狀態(tài)。
這種無狀態(tài)通信原則牧氮,使得服務(wù)端和中介能夠理解獨立的請求和響應(yīng)琼腔。 在多次請求中,同一客戶端也不再需要依賴于同一服務(wù)器踱葛,方便實現(xiàn)高可擴展和高可用性的服務(wù)端丹莲。
優(yōu)點
- 可見性——監(jiān)視系統(tǒng)不必為了確定一個請求的全部性質(zhì)去查看該請求之外的多個請求
- 可靠性——減輕了從局部故障中恢復(fù)的任務(wù)量
- 可伸縮性——不必在多個請求之間保存狀態(tài),從而允許服務(wù)器組件迅速釋放資源尸诽,并進一步簡化其實現(xiàn)甥材,因為服務(wù)器不必跨多個請求管理資源的使用情況
缺點
由于不能將狀態(tài)數(shù)據(jù)保存在服務(wù)器的共享上下文中,因此增加了一系列請求中發(fā)送的重復(fù)數(shù)據(jù)(每次交互的開銷)性含,可能會降低網(wǎng)絡(luò)性能擂达。此外,將應(yīng)用狀態(tài)放在客戶端還降低了服務(wù)器對于一致的應(yīng)用行為的控制能力胶滋,因為這樣一來板鬓,應(yīng)用就得依賴多個客戶端版本的語義的正確實現(xiàn)。
緩存
為了改善網(wǎng)絡(luò)的效率究恤,我們添加了緩存這個架構(gòu)約束俭令。緩存架構(gòu)要求一個請求的響應(yīng)中的數(shù)據(jù)被隱式地或顯式地標記為可緩存的或不可緩存的。如果響應(yīng)是緩存的部宿,那么客戶端緩存就可以為以后的相同請求重用這個響應(yīng)的數(shù)據(jù)抄腔。
優(yōu)點
添加緩存可能部分或全部消除一些交互,從而通過減少一系列交互的平均延遲時間理张,來提高效率赫蛇、可伸縮性和用戶感知的性能。
缺點
如果緩存中陳舊的數(shù)據(jù)與將請求直接發(fā)送到服務(wù)器得到的數(shù)據(jù)差別極大雾叭,那么緩存會降低可靠性悟耘。
統(tǒng)一接口
使REST架構(gòu)風格區(qū)別于其他基于網(wǎng)絡(luò)的架構(gòu)風格的核心特征是,它強調(diào)組件之間要有一個統(tǒng)一的接口织狐。通過在組件接口上應(yīng)用通用性的軟件工程原則暂幼,簡化了正特的系統(tǒng)架構(gòu)筏勒,也改善了交互的可見性。實現(xiàn)與它們所提供的服務(wù)是解耦的的旺嬉,這促進了獨立地可進化性管行。
然而,需要的付出的代價是邪媳,統(tǒng)一接口降低了效率捐顷,因為信息都使用標準化的形式來移交,而不能使用特定于應(yīng)用的需求的形式雨效。REST接口被設(shè)計為可以高效地移交大粒度的超媒體數(shù)據(jù)套菜,并針對Web的常見情況做了優(yōu)化,但是這也導(dǎo)致該接口對于其他形式的架構(gòu)交互而言不是最優(yōu)的设易。
為了獲得統(tǒng)一的接口,需要有多個架構(gòu)約束來指導(dǎo)組件的行為蛹头。REST由四個接口架構(gòu)約束來定義:
- 資源的識別(identification of resources)
- 通過表述來操作資源(manipulation of resources through representations)
- 自描述的信息(self-descriptive messages)
- 超媒體作為應(yīng)用狀態(tài)引擎(hypermedia as the engine of application state顿肺,簡稱HATEOAS)
資源的識別
每個資源都擁有一個資源標識。每個資源的資源標識可以用來唯一地標明該資源渣蜗。
通過表述來操作資源
這里說的是資源的自描述性屠尊。一個REST系統(tǒng)所返回的資源需要能夠描述自身,并提供足夠的用于操作該資源的信息耕拷,比如如何對資源進行添加讼昆,刪除以及修改等操作。也就是說骚烧,一個典型的REST服務(wù)不需要額外的文檔對如何操作資源進行說明浸赫。
自描述的信息
消息的自描述性。在REST系統(tǒng)中所傳遞的消息需要能夠提供自身如何被處理的足夠信息赃绊。例如該消息所使用的MIME類型既峡,是否可以被緩存等。
超媒體作為應(yīng)用狀態(tài)引擎
即客戶只可以通過服務(wù)端所返回各結(jié)果中所包含的信息來得到下一步操作所需要的信息碧查,如到底是向哪個URL發(fā)送請求等运敢。也就是說,一個典型的REST服務(wù)不需要額外的文檔標示通過哪些URL訪問特定類型的資源忠售,而是通過服務(wù)端返回的響應(yīng)來標示到底能在該資源上執(zhí)行什么樣的操作传惠。一個REST服務(wù)的客戶端也不需要知道任何有關(guān)哪里有什么樣的資源這種信息。
這個描述的核心是超媒體概念稻扬,換句話說:是鏈接的思想卦方。鏈接是我們在HTML中常見的概念,但是它的用處絕不局限于此(用于人們網(wǎng)絡(luò)瀏覽)泰佳≡柑考慮一下下面這個虛構(gòu)的XML片段:
<order self="http://example.com/customers/1234">
<amount>23</amount>
<product ref="http://example.com/products/4554">
<customer ref="http://example.com/customers/1234">
</customer> </product></order>
如果你觀察文檔中product和customer的鏈接困后,就可以很容易地想象到,應(yīng)用程序(已經(jīng)檢索過文檔)如何“跟隨”鏈接檢索更多的信息衬廷。當然摇予,如果使用一個遵守專用命名規(guī)范的簡單“id”屬性作為鏈接,也是可行的——但是僅限于應(yīng)用環(huán)境之內(nèi)吗跋。使用URI表示鏈接的優(yōu)雅之處在于侧戴,鏈接可以指向由不同應(yīng)用、不同服務(wù)器甚至位于另一個大陸上的不同公司提供的資源——因為URI命名規(guī)范是全球標準跌宛,構(gòu)成Web的所有資源都可以互聯(lián)互通酗宋。
超媒體原則還有一個更重要的方面——應(yīng)用“狀態(tài)”。簡而言之疆拘,實際上服務(wù)器端(如果你愿意蜕猫,也可以叫服務(wù)提供者)為客戶端(服務(wù)消費者)提供一組鏈接,使客戶端能通過鏈接將應(yīng)用從一個狀態(tài)改變?yōu)榱硪粋€狀態(tài)哎迄。目前回右,只需要記住:鏈接是構(gòu)成動態(tài)應(yīng)用的非常有效的方式漱挚。
對此原則總結(jié)如下:任何可能的情況下翔烁,使用鏈接指引可以被標識的事物(資源)。也正是超鏈接造就了現(xiàn)在的Web旨涝。
分層系統(tǒng)
為了進一步改善與互聯(lián)網(wǎng)規(guī)模這個需求相關(guān)的行為蹬屹,我們添加了分層系統(tǒng)架構(gòu)約束。分層系統(tǒng)風格通過限制組件的行為(即白华,每個組件只能“看到”與其相交互的相鄰層)慨默,將架構(gòu)分解為若干層級。通過將組件對系統(tǒng)的知識限制在單一層級內(nèi)弧腥,為整個系統(tǒng)的復(fù)雜性設(shè)置了邊界业筏,并且提高了底層獨立性。我們能夠使用層級來封裝遺留服務(wù)鸟赫,使新的服務(wù)免受遺留客戶端的影響蒜胖,做法是將不常用功能轉(zhuǎn)移到一個共享中間組件中,從而簡化組件的實現(xiàn)抛蚤。中間組件還能夠通過支持跨多個網(wǎng)絡(luò)和處理器的負載均衡台谢,來改善系統(tǒng)的可伸縮性。
中間件:
中間件是一種獨立的系統(tǒng)軟件或服務(wù)程序岁经,能夠連接兩個獨立軟件或系統(tǒng)朋沮。分布式應(yīng)用軟件借助于中間件能夠在不同的技術(shù)之間共享資源。即:中間件使得若干個相互獨立的系統(tǒng),在各自都擁有著不同的接口的情況下樊拓,仍然能通過中間件來實現(xiàn)通信纠亚。執(zhí)行中間件的一個關(guān)鍵途徑是信息的傳遞。通過中間件筋夏,應(yīng)用程序可以工作在多個平臺及OS環(huán)境中蒂胞。簡而言之,中間件即橋梁条篷。
分層系統(tǒng)的主要缺點:增加了數(shù)據(jù)處理的開銷和延遲骗随,因此降低了用戶感知的性能。對于一個支持緩存架構(gòu)約束的基于網(wǎng)絡(luò)的系統(tǒng)來說赴叹,可以通過在中間層使用共享緩存所獲得的好處來彌補這一缺點鸿染。
小結(jié)
REST架構(gòu)風格由一組經(jīng)過選擇的架構(gòu)約束組成,通過這些架構(gòu)約束在候選架構(gòu)上產(chǎn)生所期待的架構(gòu)屬性乞巧。盡管能夠獨立考慮其中每一個架構(gòu)約束涨椒,但是根據(jù)它們在公共架構(gòu)風格(common architectural styles)中的來源來對它們進行描述,使得我們理解選擇它們背后的基礎(chǔ)理論更加容易绽媒。
總結(jié)
本文試圖從本質(zhì)上來理解什么是REST蚕冬。
我們首先從REST的起源說起,發(fā)現(xiàn)REST與Web之間的本質(zhì)關(guān)系些椒,并從Web的特性,得到REST本質(zhì)上是一個分布式超媒體系統(tǒng)的應(yīng)用層解決方案這一結(jié)論掸刊。接著我們對REST免糕,即(Resource)Representational State Transfer(資源表述性狀態(tài)轉(zhuǎn)移)這個詞組進行了詳細分析,進一步得到了REST以資源為核心的架構(gòu)風格忧侧。最后石窑,我們對REST架構(gòu)的五條必要約束條件進行進一步的闡述和說明,以便讀者能夠更為深刻地理解REST蚓炬。
這篇文章到這里就算是結(jié)束了松逊,筆者在寫下這些內(nèi)容的時候依然時時感到自己知識的匱乏,以致無法更為深刻地理解REST肯夏。筆者的這篇博客经宏,既是希望能對自己所學(xué)做一個總結(jié),也希望能給其他初學(xué)者帶來一點幫助驯击。文中若有理解不當?shù)牡胤剿咐迹瑲g迎批評指點。