這本書的前面三章主要講了一下基本概念,客戶端程序,和Amazon的S3,這篇博客總結(jié)一下第四章,個(gè)人感覺(jué)有很多重要的概念。
面向資源的架構(gòu)(The Resource-Oriented Architecture),這里的資源必須要有一個(gè)URI,資源和URI的關(guān)系:一個(gè)資源可能有一個(gè)或多個(gè)URI,而一個(gè)URI只能指定一個(gè)資源。
Restful WS的特性:
1、可尋址性(Addressability)
資源通過(guò)URI來(lái)暴露給用戶,可尋址性是最基本的特性。由于可尋址性,你可以把URI保存在你的書簽里,你可以把鏈接發(fā)給別人,而不用把Html文件下載下來(lái)發(fā)給別人,也可以通過(guò)URI對(duì)資源進(jìn)行緩存。
2、無(wú)狀態(tài)性(Statelessness)
無(wú)狀態(tài)性意味著每個(gè)HTTP請(qǐng)求是完全隔離的。每次客戶端發(fā)送請(qǐng)求都必須帶上所有服務(wù)器端需要的信息。
無(wú)狀態(tài)的應(yīng)用更容易分布到有負(fù)責(zé)均衡的多臺(tái)服務(wù)器上;無(wú)狀態(tài)性也更容易緩存:緩存工具只需要看這一個(gè)請(qǐng)求,和任何其他請(qǐng)求無(wú)關(guān)。
應(yīng)用狀態(tài)和資源狀態(tài)(Application State Versus Resource State)
應(yīng)用狀態(tài)位于客戶端,而資源狀態(tài)位于服務(wù)器端,對(duì)于客戶端,每個(gè)客戶端都有各自的應(yīng)用狀態(tài),例如:在google搜索,你可能搜索某個(gè)單詞且當(dāng)前頁(yè)是第3頁(yè),我可能搜索另一個(gè)單詞且在第一頁(yè),所以每個(gè)客戶端都有一個(gè)應(yīng)用狀態(tài)。當(dāng)客戶端發(fā)起請(qǐng)求的時(shí)候,必須告訴服務(wù)器你的應(yīng)用狀態(tài),比如你當(dāng)前要看某個(gè)單詞搜索結(jié)果的第幾頁(yè),服務(wù)器端返回結(jié)果上有其他鏈接,這些鏈接客戶端可能作為未來(lái)的請(qǐng)求。
而對(duì)于資源狀態(tài),對(duì)于每個(gè)客戶端都是相同的,就是服務(wù)器上的資源。
3、表述性(Representations)
表述性,就是資源的表現(xiàn)形式,相同的資源可以有不同的表述性,比如同一個(gè)bug列表可以用XML文檔表示,也可以用文本方式表示等等。對(duì)于同一資源的不同的Representation,如何知道客戶端請(qǐng)求哪一種呢?作者建議不同的Representation使用不同的URI。
4、連通性(Links and Connectedness)
簡(jiǎn)單點(diǎn)說(shuō),就是返回的結(jié)果中有對(duì)其他資源的鏈接(URI),比如google搜索,搜索結(jié)果可能有其他頁(yè)的鏈接。
5、統(tǒng)一的接口(The Uniform Interface)
也就是說(shuō)Restful WS使用HTTP的基本方法作為他的方法的表示,主要使用HTTP的四個(gè)方法:GET,PUT,DELETE,POST。HEAD和OPTIONS用的比較少。
取得某個(gè)資源的表述的時(shí)候使用GET。
創(chuàng)建一個(gè)新的資源的時(shí)候,PUT到一個(gè)新的URI,或者POST到一個(gè)已經(jīng)存在的URI。
修改資源,使用PUT到存在的URI。
刪除資源使用DELETE。
PUT和POST都可以創(chuàng)建新的資源,那有什么區(qū)別呢?POST可以創(chuàng)建從屬資源,如一個(gè)webblog程序通過(guò)資源(/weblogs/myweblog)暴露每個(gè)blog,而某個(gè)blog下面的條目作為從屬資源為/weblogs/myweblog/entries/1,當(dāng)你需要增加一個(gè)條目的時(shí)候,你可以POST到父資源/weblogs/myweblog,同樣PUT也可以完成這個(gè)工作,在這里POST和PUT的區(qū)別是:當(dāng)客戶端可以控制新資源的URI的時(shí)候,則使用PUT,比如blog的下面的某篇文章使用名字來(lái)訪問(wèn),如/weblogs/myweblog/entries/restful_ws_1(這樣某個(gè)博客下面的文章不能重復(fù)),則當(dāng)你發(fā)表一篇新文章的時(shí)候,可以PUT到新的URI如/weblogs/myweblog/entries/restful_ws_2來(lái)創(chuàng)建資源。而如果客戶端不能控制URI的時(shí)候,比如blog是通過(guò)服務(wù)器端某個(gè)序列號(hào)來(lái)訪問(wèn),客戶端是無(wú)法知道下一個(gè)序號(hào)是什么,這時(shí)只能使用POST,這種POST如果創(chuàng)建成功,則返回201,響應(yīng)頭中的Location可以保護(hù)新創(chuàng)建資源的URI。
還有一個(gè)區(qū)別,POST對(duì)某個(gè)存在的資源更新時(shí),一般是追加(append),比如說(shuō)對(duì)某個(gè)日志文件做POST,則把日志追加到原日志的后面。如果是PUT則進(jìn)行的是替換,所以PUT是等冪的,而POST不是(后面會(huì)講)。
安全(Safety)
GET和HEAD方法只是獲取資源的表述,所以是安全的。當(dāng)然也可能有一些副作用,比如有些服務(wù)端會(huì)記錄GET的次數(shù)等。
等冪性(Idempotence)
等冪性簡(jiǎn)單點(diǎn)說(shuō)就是一次請(qǐng)求和多次請(qǐng)求,資源的狀態(tài)是一樣。比如GET和HEAD,不論你請(qǐng)求多少次,資源還是在那里。請(qǐng)注意,DELETE和PUT也是等冪的,以為對(duì)同一個(gè)資源刪除一次或者多次,結(jié)果是一樣的,就是資源被刪除了,不存在了。為什么說(shuō)PUT也是等冪的?當(dāng)你PUT一個(gè)新資源的時(shí)候,資源被創(chuàng)建,再次PUT這個(gè)URI的時(shí)候,資源還是沒(méi)變。當(dāng)你PUT一個(gè)存在的資源時(shí),更新了資源,再次PUT的時(shí)候,還是更新成這個(gè)樣子。在PUT更新的時(shí)候,不能做相對(duì)的更新(依賴資源現(xiàn)在的狀態(tài)),比如每次對(duì)一個(gè)數(shù)加1,這樣資源狀態(tài)就會(huì)變化。應(yīng)該每次更新成某個(gè)數(shù),比如把某個(gè)數(shù)變成4,則無(wú)論多少次PUT,值都是4,這樣就是等冪了。
我們?cè)O(shè)計(jì)Restful WS的時(shí)候,GET,HEAD, PUT, DELETE一定要設(shè)計(jì)成等冪的。由于網(wǎng)絡(luò)是不可靠的,安全性和等冪性就顯得特別重要。如果一次請(qǐng)求,服務(wù)器收到處理以后,客戶端沒(méi)有收到相應(yīng),客戶端會(huì)再次請(qǐng)求,如果沒(méi)有等冪性保障,就會(huì)發(fā)生意想不到的問(wèn)題。
POST是不安全也不等冪的,還是拿weblog的例子,如果兩次POST相同的博文,則會(huì)產(chǎn)生兩個(gè)資源,URI可能是這樣/weblogs/myweblog/entries/1和/weblogs/myweblog/entries/2,盡管他們的內(nèi)容是一摸一樣的。