理解本質(zhì)的REST

REST本身是一個高度抽象化的架構(gòu)風(fēng)格,因而總是很難對它有一個比較深入且印象深刻的理解。寫這篇文章的目的,是自己對學(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)風(fēng)格。它是一種針對網(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)形式進(jì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é)議專家組負(fù)責(zé)人
  • Apache HTTP服務(wù)器的核心開發(fā)者
  • Apache軟件基金會合作創(chuàng)始人
Roy Thomas Fielding

一張圖說明REST的由來:

REST的由來

好吧,這是一張很簡陋的圖,不過用來解釋REST的由來足夠了。
故事得從遠(yuǎn)古時期的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é)議專家組的負(fù)責(zé)人,負(fù)責(zé)統(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ā)布之后的十年里,都沒有多少人認(rèn)為有修訂的必要。
Fielding在完成HTTP/1.1協(xié)議的設(shè)計工作之后,回到了加州大學(xué)歐文分校繼續(xù)攻讀自己的博士學(xué)位。第二年(2000年)在他的博士學(xué)位論文Architectural Styles and the Design of Network-based Software Architectures中(中文版名為《架構(gòu)風(fēng)格與基于網(wǎng)絡(luò)的軟件架構(gòu)設(shè)計》),F(xiàn)ielding更為系統(tǒng)、嚴(yán)謹(jǐn)?shù)仃U述了這套理論框架,并且使用這套理論框架推導(dǎo)出了一種新的架構(gòu)風(fēng)格,并且為這種架構(gòu)風(fēng)格取了一個令人輕松愉快的名字“REST”——Representational State Transfer(表述性狀態(tài)轉(zhuǎn)移)的縮寫。
這便是REST的由來,可以看出,REST架構(gòu)風(fēng)格,是通過推導(dǎo)web的技術(shù)架構(gòu)因素層面而總結(jié)出來的,總結(jié)出來的理論框架被用來指導(dǎo)HTTP/1.1協(xié)議的設(shè)計方向。那么我們可以這樣理解,REST是Web自身的架構(gòu)風(fēng)格,REST是HTTP/1.1協(xié)議等Web規(guī)范的設(shè)計指導(dǎo)原則,HTTP/1.1協(xié)議正是為實現(xiàn)REST風(fēng)格的架構(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é)點(diǎn)組織成一個互為關(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)運(yùn)行的一項服務(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)的核心部分是由三個標(biāo)準(zhǔn)構(gòu)成的:

  • 統(tǒng)一資源標(biāo)識符(URI),這是一個統(tǒng)一的為資源定位的系統(tǒng)。
  • 超文本傳送協(xié)議(HTTP),它負(fù)責(zé)規(guī)定客戶端和服務(wù)器怎樣互相交流。
  • 超文本標(biāo)記語言(HTML),作用是定義超文本文檔的結(jié)構(gòu)和格式。

總結(jié)來說,web是一個由許多相互鏈接的超文本組成的系統(tǒng),它使用URI來定位系統(tǒng)中的每一個資源,并通過HTTP協(xié)議進(jìn)行數(shù)據(jù)的交互。
更抽象的說,Web是一個分布式信息系統(tǒng),為超文本文件和其他對象(資源)提供訪問接口和訪問機(jī)制。
理解了什么是web,我們便可以更好地理解什么是REST了。作為web自身的架構(gòu)風(fēng)格,我們直接給出結(jié)論:REST本質(zhì)上是一種分布式超媒體系統(tǒng)的應(yīng)用層解決方案,它為資源互通和資源管理的分離提出了一系列架構(gòu)約束和原則,得到一個功能強(qiáng)、性能好、適宜通信的以網(wǎng)絡(luò)為基礎(chǔ)的應(yīng)用軟件架構(gòu)。
這個結(jié)論依然很難理解,但我們需要對此有一個概念了解。接下來我們會對REST進(jìn)行更為詳細(xì)的介紹。

REST詞組

要理解REST,首先需要理解(Resource)Representational State Transfer這個詞組。

資源(Resource)

REST對于信息的核心抽象是資源。任何能被命名的信息都能作為一個資源:一份文檔、一個與時間相關(guān)的服務(wù)(例如,“洛杉磯今日的天氣”),一個其他資源的集合、一個非虛擬的對象(例如,人)等等。
換句話說,可以作為創(chuàng)作者的超文本引用的目標(biāo)(the target of an author's hypertext reference)的任何概念都必須符合資源的定義。資源是到一組實體的概念性映射(a conceptual mapping),而不是在任何特定時刻與該映射相關(guān)聯(lián)的實體本身。
更精確地說,資源R是一個隨時間變化的成員函數(shù)

該函數(shù)根據(jù)時間t將資源映射到一個實體或值的集合,集合中的值可能是資源表述(resource representations)和/或資源標(biāo)識符(resource identifiers)(兩者是等價的)。
對于一個資源來說,唯一必須靜態(tài)的是映射的語義,因為語義才是區(qū)別資源的關(guān)鍵。
正是資源的這個抽象定義,使得Web架構(gòu)的核心功能得以實現(xiàn)。首先,它包含了很多信息的來源,并沒有人為地通過類型或?qū)崿F(xiàn)對它們加以區(qū)分,從而實現(xiàn)了通用性。其次,它允許引用到表述的延遲綁定,從而支持基于請求的性質(zhì)來進(jìn)行內(nèi)容協(xié)商。最后,它允許創(chuàng)作者引用一個概念而不是引用此概念的某個單獨(dú)的表述,從而使得當(dāng)表述改變時無需修改所有的現(xiàn)有鏈接(假設(shè)創(chuàng)作者使用了正確地標(biāo)識符)

如何來理解“對于一個資源來說,唯一必須靜態(tài)的是映射的語義,因為語義才是區(qū)別資源的關(guān)鍵”這句話呢?舉一個簡單的例子來說明一下:
“一個APP的當(dāng)前版本”是一個資源,而“一個APP的最穩(wěn)定版本”也是一個資源,盡管這兩個資源在某個時刻上可能會映射到相同的值,但它們是是截然不同的,且兩個資源能夠被單獨(dú)地標(biāo)識和引用。

資源標(biāo)識符

REST使用資源標(biāo)識符來表示組件之間交互所涉及的特定資源。REST連接器提供了訪問和操作資源的值集合的一個通用的接口,而無須關(guān)心其成員函數(shù)(membership function)是如何定義的,或者處理請求的軟件是何種類型。由命名權(quán)威(naming authority)來為資源分配資源標(biāo)識符,使得引用資源成為可能,映射的語義有效性也由同樣的命名權(quán)威來負(fù)責(zé)維護(hù)(例如,確保成員函數(shù)不會改變)。
傳統(tǒng)的超文本系統(tǒng)通常只在一個封閉的或局部的環(huán)境中運(yùn)行,它們使用隨信息的變化而改變的唯一節(jié)點(diǎn)或文檔標(biāo)識符,并依賴鏈接服務(wù)器(link server)以獨(dú)立于內(nèi)容的方式來維護(hù)引用。因為集中式的鏈接服務(wù)器完全無法滿足Web的超大規(guī)模和跨越多個組織領(lǐng)域的需求,所以REST采用了其他的方式——以來資源的創(chuàng)作者來選擇最符合被標(biāo)識的概念本質(zhì)的資源標(biāo)識符。

資源標(biāo)識符為訪問和操作資源的值集合提供了一個通用的接口。換句話說,我們抽象出來的資源都應(yīng)該是可標(biāo)識的,都應(yīng)該擁有一個明顯的ID——在Web中,代表ID的統(tǒng)一概念是:URI(統(tǒng)一資源標(biāo)識符)。URI構(gòu)成了一個全局命名空間,使用URI標(biāo)識關(guān)鍵資源意味著這些資源獲得了一個唯一、全局的ID。
舉個簡單的例子:如果在一個類似于Amazon.com的在線商城中,沒有用唯一的ID(一個URI)標(biāo)識它的每一件商品,可想而知這將是多么可怕的業(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組件使用表述來捕獲某個資源的當(dāng)前狀態(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)風(fēng)格是對分布式超媒體系統(tǒng)中的架構(gòu)元素的一種抽象。
在web中,具體而言:

  • 每一個URI代表一種資源;
  • 客戶端和服務(wù)器之間,傳遞這種資源的某種表現(xiàn)層;
  • 客戶端通過四個HTTP動詞,對服務(wù)器端資源進(jìn)行操作,實現(xiàn)"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。

我們再來換一個角度,以搭建系統(tǒng)的角色來思考這個問題:
在web中,為了獲取我們需要的分布在不同地域的超媒體資源,我們該如何設(shè)計這個系統(tǒng)?顯然,web中有著大量的,分布在不同地方的各種類型的資源。我們需要提供的是一個大型分布式超媒體系統(tǒng)的應(yīng)用層解決方案。
首先我們需要為所需的數(shù)據(jù)設(shè)定唯一標(biāo)識,因此我們將數(shù)據(jù)進(jìn)行抽象為資源,并使用統(tǒng)一資源標(biāo)識符(URI)為每個資源設(shè)定ID,這樣我們就有辦法來操作每個資源。
那么該如何操作資源呢?換句話說,當(dāng)我們看到一個URI并將它輸入到瀏覽器中是,為何瀏覽器知道該怎樣處理這個URI?事實上,瀏覽器知道如何去處理URI的原因在于:所有的資源都支持同樣的接口(URI),支持一套同樣的方法(HTTP動詞)。這樣,當(dāng)我們自己按照這種方式來定義我們自己的資源時,web中的其他人便可以輕松的獲取這些資源。
獲取資源時,我們可能需要不同的呈現(xiàn)方式或是需求,因此我們需要對資源進(jìn)行表述,使其表現(xiàn)為我們需要的形式。

從分布式系統(tǒng)的角度來看REST,我們發(fā)現(xiàn)以資源為核心的REST確實提供了一種解決大型分布式資源系統(tǒng)的解決方案,而web的成功也確實驗證了這套理論的正確性。

REST的架構(gòu)約束條件

REST作為一種組織web服務(wù)的架構(gòu)風(fēng)格,提出了一系列架構(gòu)級約束。如果一個系統(tǒng)滿足這些約束,那該系統(tǒng)就被稱為是RESTful的。接下來,我們會逐條說明REST的五條必要約束。

客戶/服務(wù)器模型

通信只能由客戶端單方面發(fā)起,表現(xiàn)為請求-響應(yīng)的形式。

客戶-服務(wù)器約束背后的原則是分離關(guān)注點(diǎn)。通過分離用戶界面和數(shù)據(jù)存儲這兩個關(guān)注點(diǎn),我們改善了用戶界面跨多個平臺的可移植性;同時通過簡化服務(wù)器組件,改善了系統(tǒng)的可伸縮性。然而,對于Web來說,最重要的是這種關(guān)注點(diǎn)的分離使得組件可獨(dú)立地進(jì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),客戶端負(fù)責(zé)維護(hù)應(yīng)用狀態(tài),而服務(wù)端維護(hù)資源狀態(tài)。 客戶端與服務(wù)端的交互必須是無狀態(tài)的,并在每一次請求中包含處理該請求所需的一切信息。服務(wù)端不需要在請求間保留應(yīng)用狀態(tài),只有在接受到實際請求的時候,服務(wù)端才會關(guān)注應(yīng)用狀態(tài)。
這種無狀態(tài)通信原則,使得服務(wù)端和中介能夠理解獨(dú)立的請求和響應(yīng)。 在多次請求中,同一客戶端也不再需要依賴于同一服務(wù)器,方便實現(xiàn)高可擴(kuò)展和高可用性的服務(wù)端。

優(yōu)點(diǎn)

  • 可見性——監(jiān)視系統(tǒng)不必為了確定一個請求的全部性質(zhì)去查看該請求之外的多個請求
  • 可靠性——減輕了從局部故障中恢復(fù)的任務(wù)量
  • 可伸縮性——不必在多個請求之間保存狀態(tài),從而允許服務(wù)器組件迅速釋放資源,并進(jìn)一步簡化其實現(xiàn),因為服務(wù)器不必跨多個請求管理資源的使用情況

缺點(diǎn)

由于不能將狀態(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ù)被隱式地或顯式地標(biāo)記為可緩存的或不可緩存的。如果響應(yīng)是緩存的,那么客戶端緩存就可以為以后的相同請求重用這個響應(yīng)的數(shù)據(jù)。

優(yōu)點(diǎn)

添加緩存可能部分或全部消除一些交互,從而通過減少一系列交互的平均延遲時間,來提高效率、可伸縮性和用戶感知的性能。

缺點(diǎn)

如果緩存中陳舊的數(shù)據(jù)與將請求直接發(fā)送到服務(wù)器得到的數(shù)據(jù)差別極大,那么緩存會降低可靠性。

統(tǒng)一接口

使REST架構(gòu)風(fēng)格區(qū)別于其他基于網(wǎng)絡(luò)的架構(gòu)風(fēng)格的核心特征是,它強(qiáng)調(diào)組件之間要有一個統(tǒng)一的接口。通過在組件接口上應(yīng)用通用性的軟件工程原則,簡化了正特的系統(tǒng)架構(gòu),也改善了交互的可見性。實現(xiàn)與它們所提供的服務(wù)是解耦的的,這促進(jìn)了獨(dú)立地可進(jìn)化性。
然而,需要的付出的代價是,統(tǒng)一接口降低了效率,因為信息都使用標(biāo)準(zhǔn)化的形式來移交,而不能使用特定于應(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)

資源的識別

每個資源都擁有一個資源標(biāo)識。每個資源的資源標(biāo)識可以用來唯一地標(biāo)明該資源。

通過表述來操作資源

這里說的是資源的自描述性。一個REST系統(tǒng)所返回的資源需要能夠描述自身,并提供足夠的用于操作該資源的信息,比如如何對資源進(jìn)行添加,刪除以及修改等操作。也就是說,一個典型的REST服務(wù)不需要額外的文檔對如何操作資源進(jìn)行說明。

自描述的信息

消息的自描述性。在REST系統(tǒng)中所傳遞的消息需要能夠提供自身如何被處理的足夠信息。例如該消息所使用的MIME類型,是否可以被緩存等。

超媒體作為應(yīng)用狀態(tài)引擎

即客戶只可以通過服務(wù)端所返回各結(jié)果中所包含的信息來得到下一步操作所需要的信息,如到底是向哪個URL發(fā)送請求等。也就是說,一個典型的REST服務(wù)不需要額外的文檔標(biāo)示通過哪些URL訪問特定類型的資源,而是通過服務(wù)端返回的響應(yīng)來標(biāo)示到底能在該資源上執(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)檢索過文檔)如何“跟隨”鏈接檢索更多的信息。當(dāng)然,如果使用一個遵守專用命名規(guī)范的簡單“id”屬性作為鏈接,也是可行的——但是僅限于應(yīng)用環(huán)境之內(nèi)。使用URI表示鏈接的優(yōu)雅之處在于,鏈接可以指向由不同應(yīng)用、不同服務(wù)器甚至位于另一個大陸上的不同公司提供的資源——因為URI命名規(guī)范是全球標(biāo)準(zhǔn),構(gòu)成Web的所有資源都可以互聯(lián)互通。
超媒體原則還有一個更重要的方面——應(yīng)用“狀態(tài)”。簡而言之,實際上服務(wù)器端(如果你愿意,也可以叫服務(wù)提供者)為客戶端(服務(wù)消費(fèi)者)提供一組鏈接,使客戶端能通過鏈接將應(yīng)用從一個狀態(tài)改變?yōu)榱硪粋€狀態(tài)。目前,只需要記?。烘溄邮菢?gòu)成動態(tài)應(yīng)用的非常有效的方式。
對此原則總結(jié)如下:任何可能的情況下,使用鏈接指引可以被標(biāo)識的事物(資源)。也正是超鏈接造就了現(xiàn)在的Web。

分層系統(tǒng)

為了進(jìn)一步改善與互聯(lián)網(wǎng)規(guī)模這個需求相關(guān)的行為,我們添加了分層系統(tǒng)架構(gòu)約束。分層系統(tǒng)風(fēng)格通過限制組件的行為(即,每個組件只能“看到”與其相交互的相鄰層),將架構(gòu)分解為若干層級。通過將組件對系統(tǒng)的知識限制在單一層級內(nèi),為整個系統(tǒng)的復(fù)雜性設(shè)置了邊界,并且提高了底層獨(dú)立性。我們能夠使用層級來封裝遺留服務(wù),使新的服務(wù)免受遺留客戶端的影響,做法是將不常用功能轉(zhuǎn)移到一個共享中間組件中,從而簡化組件的實現(xiàn)。中間組件還能夠通過支持跨多個網(wǎng)絡(luò)和處理器的負(fù)載均衡,來改善系統(tǒng)的可伸縮性。


中間件:
中間件是一種獨(dú)立的系統(tǒng)軟件或服務(wù)程序,能夠連接兩個獨(dú)立軟件或系統(tǒng)。分布式應(yīng)用軟件借助于中間件能夠在不同的技術(shù)之間共享資源。即:中間件使得若干個相互獨(dú)立的系統(tǒng),在各自都擁有著不同的接口的情況下,仍然能通過中間件來實現(xiàn)通信。執(zhí)行中間件的一個關(guān)鍵途徑是信息的傳遞。通過中間件,應(yīng)用程序可以工作在多個平臺及OS環(huán)境中。簡而言之,中間件即橋梁。

分層系統(tǒng)的主要缺點(diǎn):增加了數(shù)據(jù)處理的開銷和延遲,因此降低了用戶感知的性能。對于一個支持緩存架構(gòu)約束的基于網(wǎng)絡(luò)的系統(tǒng)來說,可以通過在中間層使用共享緩存所獲得的好處來彌補(bǔ)這一缺點(diǎn)。

小結(jié)

REST架構(gòu)風(fēng)格由一組經(jīng)過選擇的架構(gòu)約束組成,通過這些架構(gòu)約束在候選架構(gòu)上產(chǎn)生所期待的架構(gòu)屬性。盡管能夠獨(dú)立考慮其中每一個架構(gòu)約束,但是根據(jù)它們在公共架構(gòu)風(fēng)格(common architectural styles)中的來源來對它們進(jìn)行描述,使得我們理解選擇它們背后的基礎(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)移)這個詞組進(jìn)行了詳細(xì)分析,進(jìn)一步得到了REST以資源為核心的架構(gòu)風(fēng)格。最后,我們對REST架構(gòu)的五條必要約束條件進(jìn)行進(jìn)一步的闡述和說明,以便讀者能夠更為深刻地理解REST。
這篇文章到這里就算是結(jié)束了,筆者在寫下這些內(nèi)容的時候依然時時感到自己知識的匱乏,以致無法更為深刻地理解REST。筆者的這篇博客,既是希望能對自己所學(xué)做一個總結(jié),也希望能給其他初學(xué)者帶來一點(diǎn)幫助。文中若有理解不當(dāng)?shù)牡胤?,歡迎批評指點(diǎn)。

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一說到REST,我想大家的第一反應(yīng)就是“啊,就是那種前后臺通信方式?!钡窃谝笤敿?xì)講述它所提出的各個約束,以及如...
    時待吾閱讀 3,602評論 0 19
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,695評論 19 139
  • 轉(zhuǎn)自 REST 協(xié)議的認(rèn)識 客戶端服務(wù)端例子 1、協(xié)議介紹:轉(zhuǎn) http://blog.csdn.net/colo...
    ZMJun閱讀 2,361評論 1 2
  • 心依然熾熱著 就像眼前的日炎一樣 心中依然充斥 想你,卻也無能無力 說著奮斗 卻也不知怎樣 才會重獲新生 終日奔波...
    愛花癡閱讀 281評論 0 0
  • 完成文章的修改,排版結(jié)束,準(zhǔn)備點(diǎn)擊發(fā)布,已是華燈初上后的夜晚八點(diǎn)半。 窗外,別人家的氛圍剛進(jìn)入飯后的休閑時光,飯飽...
    老顯閱讀 1,088評論 9 17

友情鏈接更多精彩內(nèi)容