今天抽空整理些有關(guān)rest方面的理論。主要參考了幾篇網(wǎng)上的文章,做了些整理,原文見(jiàn)附錄。
一、起源
越來(lái)越多的人開(kāi)始意識(shí)到,網(wǎng)站即軟件,而且是一種新型的軟件。
這種"互聯(lián)網(wǎng)軟件"采用客戶端/服務(wù)器模式,建立在分布式體系上,通過(guò)互聯(lián)網(wǎng)通信,具有高延時(shí)(high latency)、高并發(fā)等特點(diǎn)。
網(wǎng)站開(kāi)發(fā),完全可以采用軟件開(kāi)發(fā)的模式。但是傳統(tǒng)上,軟件和網(wǎng)絡(luò)是兩個(gè)不同的領(lǐng)域,很少有交集;軟件開(kāi)發(fā)主要針對(duì)單機(jī)環(huán)境,網(wǎng)絡(luò)則主要研究系統(tǒng)之間的通信。互聯(lián)網(wǎng)的興起,使得這兩個(gè)領(lǐng)域開(kāi)始融合,現(xiàn)在我們必須考慮,如何開(kāi)發(fā)在互聯(lián)網(wǎng)環(huán)境中使用的軟件。
RESTful架構(gòu),就是一種互聯(lián)網(wǎng)軟件架構(gòu)。它結(jié)構(gòu)清晰、符合標(biāo)準(zhǔn)、易于理解、擴(kuò)展方便,所以正得到越來(lái)越多網(wǎng)站的采用。
二、名稱
Fielding將他對(duì)互聯(lián)網(wǎng)軟件的架構(gòu)原則,定名為REST,即Representational State Transfer的縮寫(xiě)。我對(duì)這個(gè)詞組的翻譯是"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。
如果一個(gè)架構(gòu)符合REST原則,就稱它為RESTful架構(gòu)。
要理解RESTful架構(gòu),最好的方法就是去理解Representational State Transfer這個(gè)詞組到底是什么意思,它的每一個(gè)詞代表了什么涵義。如果你把這個(gè)名稱搞懂了,也就不難體會(huì)REST是一種什么樣的設(shè)計(jì)。
三、資源(Resources)
REST的名稱"表現(xiàn)層狀態(tài)轉(zhuǎn)化"中,省略了主語(yǔ)。"表現(xiàn)層"其實(shí)指的是"資源"(Resources)的"表現(xiàn)層"。
所謂"資源",就是網(wǎng)絡(luò)上的一個(gè)實(shí)體,或者說(shuō)是網(wǎng)絡(luò)上的一個(gè)具體信息。它可以是一段文本、一張圖片、一首歌曲、一種服務(wù),總之就是一個(gè)具體的實(shí)在。你可以用一個(gè)URI(統(tǒng)一資源定位符)指向它,每種資源對(duì)應(yīng)一個(gè)特定的URI。要獲取這個(gè)資源,訪問(wèn)它的URI就可以,因此URI就成了每一個(gè)資源的地址或獨(dú)一無(wú)二的識(shí)別符。
所謂"上網(wǎng)",就是與互聯(lián)網(wǎng)上一系列的"資源"互動(dòng),調(diào)用它的URI。
四、表現(xiàn)層(Representation)
"資源"是一種信息實(shí)體,它可以有多種外在表現(xiàn)形式。我們把"資源"具體呈現(xiàn)出來(lái)的形式,叫做它的"表現(xiàn)層"(Representation)。
比如,文本可以用txt格式表現(xiàn),也可以用HTML格式、XML格式、JSON格式表現(xiàn),甚至可以采用二進(jìn)制格式;圖片可以用JPG格式表現(xiàn),也可以用PNG格式表現(xiàn)。
URI只代表資源的實(shí)體,不代表它的形式。嚴(yán)格地說(shuō),有些網(wǎng)址最后的".html"后綴名是不必要的,因?yàn)檫@個(gè)后綴名表示格式,屬于"表現(xiàn)層"范疇,而URI應(yīng)該只代表"資源"的位置。它的具體表現(xiàn)形式,應(yīng)該在HTTP請(qǐng)求的頭信息中用Accept和Content-Type字段指定,這兩個(gè)字段才是對(duì)"表現(xiàn)層"的描述。
五、狀態(tài)轉(zhuǎn)化(State Transfer)
訪問(wèn)一個(gè)網(wǎng)站,就代表了客戶端和服務(wù)器的一個(gè)互動(dòng)過(guò)程。在這個(gè)過(guò)程中,勢(shì)必涉及到數(shù)據(jù)和狀態(tài)的變化。
互聯(lián)網(wǎng)通信協(xié)議HTTP協(xié)議,是一個(gè)無(wú)狀態(tài)協(xié)議。這意味著,所有的狀態(tài)都保存在服務(wù)器端。因此,如果客戶端想要操作服務(wù)器,必須通過(guò)某種手段,讓服務(wù)器端發(fā)生"狀態(tài)轉(zhuǎn)化"(State Transfer)。而這種轉(zhuǎn)化是建立在表現(xiàn)層之上的,所以就是"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。
客戶端用到的手段,只能是HTTP協(xié)議。具體來(lái)說(shuō),就是HTTP協(xié)議里面,四個(gè)表示操作方式的動(dòng)詞:GET、POST、PUT、DELETE。它們分別對(duì)應(yīng)四種基本操作:GET用來(lái)獲取資源,POST用來(lái)新建資源(也可以用于更新資源),PUT用來(lái)更新資源,DELETE用來(lái)刪除資源。
六、綜述
綜合上面的解釋,我們總結(jié)一下什么是RESTful架構(gòu):
(1)每一個(gè)URI代表一種資源;
(2)客戶端和服務(wù)器之間,傳遞這種資源的某種表現(xiàn)層;
(3)客戶端通過(guò)四個(gè)HTTP動(dòng)詞,對(duì)服務(wù)器端資源進(jìn)行操作,實(shí)現(xiàn)"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。
REST關(guān)鍵原則
一個(gè)簡(jiǎn)單扼要的定義:REST定義了應(yīng)該如何正確地使用Web標(biāo)準(zhǔn),例如HTTP和URI。如果你在設(shè)計(jì)應(yīng)用程序時(shí)能堅(jiān)持REST原則,那就預(yù)示著你將會(huì)得到一個(gè)使用了優(yōu)質(zhì)Web架構(gòu)(這將讓你受益)的系統(tǒng)。總之,五條關(guān)鍵原則列舉如下:
- 為所有“事物”定義ID
- 將所有事物鏈接在一起
- 使用標(biāo)準(zhǔn)方法
- 資源多重表述
- 無(wú)狀態(tài)通信
為所有“事物”定義ID
在這里我使用了“事物”來(lái)代替更正式準(zhǔn)確的術(shù)語(yǔ)“資源”,因?yàn)橐粭l如此簡(jiǎn)單的原則,不應(yīng)該被淹沒(méi)在術(shù)語(yǔ)當(dāng)中。思考一下人們構(gòu)建的系統(tǒng),通常會(huì)找到一系列值得被標(biāo)識(shí)的關(guān)鍵抽象。每個(gè)事物都應(yīng)該是可標(biāo)識(shí)的,都應(yīng)該擁有一個(gè)明顯的ID——在Web中,代表ID的統(tǒng)一概念是:URI。URI構(gòu)成了一個(gè)全局命名空間,使用URI標(biāo)識(shí)你的關(guān)鍵資源意味著它們獲得了一個(gè)唯一、全局的ID。
值得被URI標(biāo)識(shí)的事物——資源——要比數(shù)據(jù)庫(kù)記錄抽象的多。標(biāo)識(shí)所有值得標(biāo)識(shí)的事物,領(lǐng)會(huì)這個(gè)觀念可以進(jìn)一步引導(dǎo)你創(chuàng)造出在傳統(tǒng)的應(yīng)用程序設(shè)計(jì)中不常見(jiàn)的資源:一個(gè)流程或者流程步驟、一次銷售、一次談判、一份報(bào)價(jià)請(qǐng)求——這都是應(yīng)該被標(biāo)識(shí)的事物的示例。
將所有事物鏈接在一起
接下來(lái)要討論的原則有一個(gè)有點(diǎn)令人害怕的正式描述:“超媒體被當(dāng)作應(yīng)用狀態(tài)引擎(Hypermedia as the engine of application state)”,有時(shí)簡(jiǎn)寫(xiě)為HATEOAS。(嚴(yán)格地說(shuō),這不是我說(shuō)的。)這個(gè)描述的核心是超媒體概念,換句話說(shuō):是鏈接的思想。鏈接是我們?cè)贖TML中常見(jiàn)的概念,但是它的用處絕不局限于此(用于人們網(wǎng)絡(luò)瀏覽)。
使用標(biāo)準(zhǔn)方法
在前兩個(gè)原則的討論中暗含著一個(gè)假設(shè):接收URI的應(yīng)用程序可以通過(guò)URI明確地做一些有意義的事情。如果你在公共汽車上看到一個(gè)URI,你可以將它輸入瀏覽器的地址欄中并回車——但是你的瀏覽器如何知道需要對(duì)這個(gè)URI做些什么呢?
它知道如何去處理URI的原因在于所有的資源都支持同樣的接口,一套同樣的方法(只要你樂(lè)意,也可以稱為操作)集合。在HTTP中這被叫做動(dòng)詞(verb),除了兩個(gè)大家熟知的(GET和POST)之外,標(biāo)準(zhǔn)方法集合中還包含PUT、DELETE、HEAD和OPTIONS。這些方法的含義連同行為許諾都一起定義在HTTP規(guī)范之中。
資源多重表述
在實(shí)踐中,資源多重表述還有著其它重要的好處:如果你為你的資源提供HTML和XML兩種表述方式,那這些資源不僅可以被你的應(yīng)用所用,還可以被任意標(biāo)準(zhǔn)Web瀏覽器所用——也就是說(shuō),你的應(yīng)用信息可以被所有會(huì)使用Web的人獲取到。
無(wú)狀態(tài)通信
首先,需要著重強(qiáng)調(diào)的是,雖然REST包含無(wú)狀態(tài)性(statelessness)的觀念,但這并不是說(shuō)暴露功能的應(yīng)用不能有狀態(tài)——
事實(shí)上,在大部分情況下這會(huì)導(dǎo)致整個(gè)做法沒(méi)有任何用處。REST要求狀態(tài)要么被放入資源狀態(tài)中,要么保存在客戶端上。
或者換句話說(shuō),服務(wù)器端不能保持除了單次請(qǐng)求之外的,任何與其通信的客戶端的通信狀態(tài)。這樣做的最直接的理由就是可伸縮性—— 如果服務(wù)器需要保持客戶端狀態(tài),那么大量的客戶端交互會(huì)嚴(yán)重影響服務(wù)器的內(nèi)存可用空間(footprint)。(注意,要做到無(wú)狀態(tài)通信往往需要需要一些重新設(shè)計(jì)——不能簡(jiǎn)單地將一些session狀態(tài)綁縛在URI上,然后就宣稱這個(gè)應(yīng)用是RESTful。)
但除此以外,其它方面可能顯得更為重要:無(wú)狀態(tài)約束使服務(wù)器的變化對(duì)客戶端是不可見(jiàn)的,因?yàn)樵趦纱芜B續(xù)的請(qǐng)求中,客戶端并不依賴于同一臺(tái)服務(wù)器。一個(gè)客戶端從某臺(tái)服務(wù)器上收到一份包含鏈接的文檔,當(dāng)它要做一些處理時(shí),這臺(tái)服務(wù)器宕掉了,可能是硬盤(pán)壞掉而被拿去修理,可能是軟件需要升級(jí)重啟——如果這個(gè)客戶端訪問(wèn)了從這臺(tái)服務(wù)器接收的鏈接,它不會(huì)察覺(jué)到后臺(tái)的服務(wù)器已經(jīng)改變了。
REST風(fēng)格的一個(gè)“化身”便是HTTP(以及一套相關(guān)的一套標(biāo)準(zhǔn),比如URI)。
附錄:
1.深入淺出REST
http://www.infoq.com/cn/articles/rest-introduction2.理解Restful 架構(gòu)
http://www.ruanyifeng.com/blog/2011/09/restful.html3.Rest和soap比較
http://www.infoq.com/cn/articles/rest-soap-when-to-use-each4.Rest和Rpc比較
http://xinklabi.iteye.com/blog/807220