REST不是一個(gè)標(biāo)準(zhǔn),而是一種軟件應(yīng)用架構(gòu)風(fēng)格?;赟OAP的Web服務(wù)采用RPC架構(gòu),如果說RPC是一種面向操作的架構(gòu)風(fēng)格,而REST則是一種面向資源的架構(gòu)風(fēng)格。REST是目前業(yè)界更為推崇的構(gòu)建新一代Web服務(wù)(或者Web API)的架構(gòu)風(fēng)格。由于REST僅僅是一種價(jià)格風(fēng)格,所以它是與具體的技術(shù)平臺(tái)無關(guān)的,也就是說采用REST架構(gòu)的應(yīng)用未必一定建立在Web之上,所以在正式介紹REST之前,我們先來簡單認(rèn)識(shí)一下Web。
目錄
一、TCP/IP與HTTP
二、Web資源
媒體類型
URI、URL和URN
三、HTTP事務(wù)
HTTP方法
響應(yīng)狀態(tài)碼
四、HTTP報(bào)文
如果要問大家這樣一個(gè)問題:“在過去半個(gè)世紀(jì)中,哪種信息技術(shù)對(duì)人類的影響最為深遠(yuǎn)?”,我想很多人的答案是Web(World Wide Web、WWW、W3或者萬維網(wǎng)),因?yàn)樗淖兞宋覀兊纳罘绞胶退季S方式。如果各位閱讀過W3C介紹WWW的官方文檔(“http://www.w3.org/WWW/”),應(yīng)該對(duì)它的第一句話記憶猶新——“The World Wide Web (known as "WWW', "Web" or "W3") is the universe of network-accessible information, the embodiment of human knowledge”。如果將這句話翻譯成簡潔的中文,就是“Web是(網(wǎng)絡(luò))信息的來源,知識(shí)的化身”。
Web為我們提供了一種利用HTTP協(xié)議獲取和操作網(wǎng)絡(luò)資源的方式,這些將Web服務(wù)器作為宿主的資源不僅僅包含像文字和圖片這些傳統(tǒng)的信息載體,還包含音頻和視頻這些多媒體信息。Web的核心主要體現(xiàn)在三個(gè)方面,即HTTP、超文本(Hypertext)和超媒體(Hypermedia)[1],超文本和超媒體規(guī)范了網(wǎng)絡(luò)信息的表現(xiàn)形式,而HTTP則提供了網(wǎng)絡(luò)訪問的標(biāo)準(zhǔn)協(xié)議。接下來我們就以圍繞著HTTP對(duì)Web作一下基本的介紹。
TCP/IP是以IP和TCP協(xié)議為核心的一整套網(wǎng)絡(luò)協(xié)議的總稱,所以有時(shí)候我們也稱其為TCP/IP協(xié)議簇。毫不夸張地說,TCP/IP支撐著整個(gè)互聯(lián)網(wǎng),因?yàn)樗褪腔ヂ?lián)網(wǎng)采用的網(wǎng)絡(luò)協(xié)議。TCP/IP協(xié)議簇劃分為如右圖所示的4個(gè)層次[2](應(yīng)用層、傳輸層、網(wǎng)絡(luò)層和鏈路層),構(gòu)成整個(gè)協(xié)議簇的各個(gè)子協(xié)議處于相應(yīng)層次中。
既然將整個(gè)協(xié)議簇命名為TCP/IP,那么IP和TCP自然就是其中最為核心的兩個(gè)協(xié)議了。處于網(wǎng)絡(luò)層的IP協(xié)議提供的IP數(shù)據(jù)報(bào)傳輸是不可靠的,因?yàn)樗怀兄Z盡可能地將數(shù)據(jù)報(bào)發(fā)送出去,但不能保證發(fā)送的數(shù)據(jù)報(bào)能夠成功地抵達(dá)目的地。IP協(xié)議的不可靠性還體現(xiàn)在它不能檢測數(shù)據(jù)在傳輸過程中是否發(fā)生了改變,也就是說數(shù)據(jù)的完整性得不到保證。IP協(xié)議是一個(gè)無連接(Connectionless)的網(wǎng)絡(luò)協(xié)議,每次數(shù)據(jù)報(bào)的處理對(duì)它來說均是獨(dú)立的,因此IP協(xié)議也不能提供針對(duì)有序傳輸(數(shù)據(jù)接收的順序與發(fā)送的順序一致)的保證。
雖然IP協(xié)議只能提供不可靠的數(shù)據(jù)傳輸,同時(shí)有序傳輸也得不到保證,但是建立在它之上的傳輸層協(xié)議TCP有效地解決了這兩個(gè)問題。TCP是一個(gè)基于連接的協(xié)議,數(shù)據(jù)交換雙方在進(jìn)行報(bào)文傳輸之前需要建立連接,報(bào)文傳輸結(jié)束之后需要關(guān)閉連接。這是一個(gè)雙工(Duplex)連接,數(shù)據(jù)交換的雙工均可以利用它向?qū)Ψ桨l(fā)送數(shù)據(jù)。
TCP利用“接收確認(rèn)”和“超時(shí)重傳”機(jī)制確保了數(shù)據(jù)能夠成功抵達(dá)目的地。具體來說,接收方在成功接收到數(shù)據(jù)之后會(huì)回復(fù)一個(gè)確認(rèn)消息。發(fā)送方在本地具有一個(gè)存放尚未得到確認(rèn)的已發(fā)消息的緩沖區(qū),如果發(fā)送方在一個(gè)設(shè)定的時(shí)限內(nèi)沒有接收到針對(duì)某個(gè)已發(fā)報(bào)文的確認(rèn)消息,它會(huì)從該緩存區(qū)中選擇對(duì)應(yīng)的報(bào)文進(jìn)行重新發(fā)送。在接收到確認(rèn)之后,相應(yīng)的報(bào)文會(huì)從緩存區(qū)中移除。
為了解決有序傳輸?shù)膯栴},發(fā)送方會(huì)為每個(gè)報(bào)文進(jìn)行編號(hào),報(bào)文的序號(hào)體現(xiàn)了它們被發(fā)送的順序。接收端在接收到某個(gè)報(bào)文之后,它會(huì)利用此序號(hào)判斷是否具有尚未成功接收的已發(fā)報(bào)文,如果有的話,該報(bào)文會(huì)被存放到本地的緩沖區(qū)中。等到之前發(fā)送的報(bào)文全部被接收之后,接收方按照序號(hào)對(duì)接收的報(bào)文依次向上(應(yīng)用層)遞交,成功遞交的報(bào)文會(huì)被從緩存區(qū)中移除。除了接收到“失序”的報(bào)文之外,接收方還有可能接收到重復(fù)的報(bào)文,因?yàn)闆]有報(bào)文均具有一個(gè)唯一的序號(hào),如果該序號(hào)小于已經(jīng)成功遞交或者添加到緩存區(qū)中的報(bào)文序號(hào),它會(huì)被認(rèn)為是重復(fù)接收的報(bào)文而被丟棄。
由于每個(gè)TCP報(bào)文段都具有一個(gè)16位的檢驗(yàn)和(Checksum),所以接收方可以根據(jù)它確認(rèn)數(shù)據(jù)在傳輸過程中是否被篡改。除此之外,TCP還提供了“流量控制”功能避免了雙方因緩存區(qū)大小不一致而導(dǎo)致報(bào)文丟失。具體來說,如果發(fā)送方的緩沖區(qū)大于接收方的緩存區(qū),會(huì)導(dǎo)致接收方在緩沖區(qū)已滿的情況下無法處理后續(xù)接收的報(bào)文,所以接收方會(huì)將自己緩存區(qū)剩余的大小及時(shí)通知給發(fā)送端,后者據(jù)此控制報(bào)文發(fā)送“流量”。
HTTP(Hypertext Transfer Protocol),全稱為“超文本傳輸協(xié)議”,是TCP/IP協(xié)議簇的一部分。從圖1-1可以看出,這是一個(gè)位于應(yīng)用層的網(wǎng)絡(luò)協(xié)議,在它之下的就是TCP協(xié)議。由于TCP協(xié)議是一個(gè)“可靠”的協(xié)議,HTTP自然也能提供可靠數(shù)據(jù)傳輸功能。
IP協(xié)議利用IP地址來定位數(shù)據(jù)報(bào)發(fā)送的目的地,而利用域名系統(tǒng)(DNS)可以實(shí)現(xiàn)域名與IP地址之間的轉(zhuǎn)換。TCP協(xié)議利用端口號(hào)標(biāo)識(shí)應(yīng)用程序,所以某個(gè)應(yīng)用程序在使用TCP協(xié)議進(jìn)行通信的時(shí)候必須指定目標(biāo)應(yīng)用的IP地址(或者域名)和端口號(hào)。HTTP默認(rèn)采用的端口號(hào)為80,而HTTPS(利用TLS/SSL為HTTP提供傳輸安全保障)的默認(rèn)端口號(hào)則為443,當(dāng)然在網(wǎng)絡(luò)可達(dá)的前提下,我們可以指定任意的端口。
這里所說的資源是一個(gè)寬泛的概念,任何寄宿于Web服務(wù)器可以利用HTTP協(xié)議獲取或者操作的“事物”均可以稱為資源。這也是一個(gè)抽象的概念,不僅僅是寄宿于Web服務(wù)器的某個(gè)靜態(tài)物理文件可以視為Web資源,通過Web應(yīng)用根據(jù)請(qǐng)求動(dòng)態(tài)生成的數(shù)據(jù)也是Web資源。
資源實(shí)際上是一種承載著某種信息的數(shù)據(jù),相同的信息可以采用不同形態(tài)的數(shù)據(jù)來展現(xiàn),數(shù)據(jù)的“形態(tài)”主要體現(xiàn)為展示數(shù)據(jù)所采用的格式,比如一個(gè)數(shù)據(jù)對(duì)象可以通過XML格式來表示,也可以通過JSON格式來表示。數(shù)據(jù)的處理必須依賴于一種已知的格式,所以將Web資源的形態(tài)以一種標(biāo)準(zhǔn)化的方式固定下來顯得尤為重要,這就是我們接下來著重介紹的媒體媒體(Media Type)。
不論是通過HTTP請(qǐng)求從Web服務(wù)器上獲取資源,還是利用請(qǐng)求向服務(wù)器提交資源,響應(yīng)或者請(qǐng)求的主體(Body)除了包含承載資源本身的數(shù)據(jù)之外,其報(bào)頭(Header)部分還應(yīng)該包含表示數(shù)據(jù)形態(tài)的媒體類型。
媒體類型又被稱為MIME(Multipurpose Internet Mail Extension)類型,MIME是一個(gè)互聯(lián)網(wǎng)標(biāo)準(zhǔn),它擴(kuò)展了電子郵件標(biāo)準(zhǔn),使其能夠支持非ASCII字符、二進(jìn)制格式附件等多種格式的郵件消息。由于MIME在電子郵件系統(tǒng)應(yīng)用得非常好,所以被HTTP用于描述并標(biāo)記多媒體內(nèi)容。下面的列表給出了一種常用的媒體類型。
可操作的Web資源應(yīng)該具有一個(gè) 唯一的標(biāo)識(shí)。雖然具有很多唯一性標(biāo)志符的種類可供選擇(比如GUID),但是采用URI來標(biāo)識(shí)Web資源已經(jīng)成為了一種共識(shí),實(shí)際上URI的全稱為“統(tǒng)一資源標(biāo)志符(Uniform Resource Identifier)”。
我想有很多人弄不清楚URI和URL之間的區(qū)別,有人甚至覺得這是同一概念的不同表述而已。一個(gè)URL肯定是一個(gè)URI,但是一個(gè)URI并不一定是一個(gè)URL,URL僅僅是URI的一種表現(xiàn)形式而已。兩者的差異其實(shí)可以直接從其命名來區(qū)分,URI是Web資源的標(biāo)志符,所以只要求它具有“標(biāo)識(shí)性”即可;URL全稱為“統(tǒng)一資源定位符(Uniform Resource Locator)”,所以除了標(biāo)識(shí)性之外,它還具有定位的功能,用于描述Web資源所在的位置。
URL不僅僅用于定位目標(biāo)資源所在的位置,還指名了獲取資源所采用的協(xié)議,一個(gè)完整的URL包含協(xié)議名稱、主機(jī)名稱(IP地址或者域名)、端口號(hào)、路徑和查詢字符串5個(gè)部分。比如對(duì)于“ http://www.artech.com:8080/images/photo.png?size=small”這樣一個(gè)URL,上述的5個(gè)部分分別是“http”、“www.artech.com”、“8080”、“/images/photo.png”和“?size=small”。
除了URL,URN也是URI的一種表現(xiàn)形式,URN全稱“統(tǒng)一資源定位符(Uniform Resource Name)”。URN與資源所在的位置無關(guān),倘若采用URN來唯一標(biāo)識(shí)某個(gè)資源,在位置發(fā)生改變的時(shí)候標(biāo)志符依然可以保持不變。URN一般也不會(huì)涉及到獲取被標(biāo)識(shí)資源采用的網(wǎng)絡(luò)協(xié)議,所以不需要為利用不同協(xié)議訪問的相同資源定義不同的標(biāo)志符。
雖然TCP是一種基于連接的傳輸層協(xié)議,并且保存雙方針對(duì)同一個(gè)連接的多輪消息交換的會(huì)話狀態(tài),但是建立其上的HTTP則是一種無狀態(tài)的網(wǎng)絡(luò)協(xié)議。HTTP采用簡單的“請(qǐng)求/響應(yīng)”消息交換模式,一次HTTP事務(wù)(Transaction)始于請(qǐng)求的發(fā)送,止于響應(yīng)的接收。針對(duì)客戶端和Web服務(wù)器的多次消息交換來說,每個(gè)HTTP事務(wù)均是相互獨(dú)立的。
HTTP采用簡單的請(qǐng)求/響應(yīng)模式的消息交換旨在實(shí)現(xiàn)針對(duì)某個(gè)Web資源的某種操作。至于針對(duì)資源的操作類型,不外乎CRUD(Create、Retrieve、Update和Delete)而已。一個(gè)HTTP請(qǐng)求除了利用URI標(biāo)志目標(biāo)資源之外,還需要通過HTTP方法(HTTP Method或者HTTP Verb)指名針對(duì)資源的操作類型。我們常用的HTTP方法 包括GET、POST、PUT、DELETE、HEAD、OPTIONS、TRACE、CONNECTION和PATCH等,我們將在《設(shè)計(jì)篇》以REST的視角來對(duì)它們進(jìn)行詳細(xì)介紹。
針對(duì)客戶端向Web服務(wù)器發(fā)送的任意一個(gè)HTTP請(qǐng)求,不論在何種情況下得到一個(gè)響應(yīng),每個(gè)響應(yīng)均具有一個(gè)由3位數(shù)字表示的狀態(tài)碼和相應(yīng)的描述文字。不同數(shù)值的狀態(tài)碼體現(xiàn)了不同類型的響應(yīng)狀態(tài),W3C對(duì)響應(yīng)狀態(tài)碼的范圍作了如下的規(guī)范。
客戶端和Web服務(wù)器在一次HTTP事務(wù)中交換的消息被稱為HTTP報(bào)頭,客戶端發(fā)送給服務(wù)器的請(qǐng)求消息被稱為請(qǐng)求報(bào)文,服務(wù)器返回給客戶端的響應(yīng)消息被稱為響應(yīng)報(bào)頭。請(qǐng)求報(bào)文和響應(yīng)報(bào)頭采用純文本編碼,由一行行簡單的字符串組成。一個(gè)完整的HTTP報(bào)文由如下三個(gè)部分構(gòu)成。
接下來我們看看一個(gè)具體HTTP報(bào)文具有怎樣的結(jié)構(gòu)。下面這個(gè)文本片段反映的是我們通過Chrome瀏覽器訪問微軟的官網(wǎng)(www.microsoft. com)對(duì)應(yīng)的HTTP請(qǐng)求,起始行體現(xiàn)了HTTP請(qǐng)求的三個(gè)基本屬性,即HTTP方法(GET)、目標(biāo)資源(http://www.microsoft.com/en-us/default.aspx)和協(xié)議版本(HTTP/1.1)。
1: GET http://www.microsoft.com/en-us/default.aspx HTTP/1.1
2: Host: www.microsoft.com
3: Connection: keep-alive
4: Cache-Control: max-age=0
5: User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.75 Safari/535.7
6: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
7: Accept-Encoding: gzip,deflate,sdch
8: Accept-Language: en-US,en;q=0.8
9: Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
10: Cookie: ...
上述這個(gè)請(qǐng)求報(bào)文不具有主體,所以起始行之外的所有內(nèi)容均為報(bào)頭集合,我們們可以根據(jù)這些報(bào)頭獲得主機(jī)名稱、采用的緩存策略、瀏覽器相關(guān)信息、以及客戶端支持的媒體類型(Media Type)、編碼方式、語言和字符集等。
前面的HTTP請(qǐng)求通過瀏覽器發(fā)送給服務(wù)端之后會(huì)接收到具有如下結(jié)構(gòu)的響應(yīng)報(bào)文,我們可以此從它的起始行得到采用的HTTP版本(HTTP/1.1)和響應(yīng)狀態(tài)碼(“200 OK”,表示請(qǐng)求被正常接收處理)。響應(yīng)的內(nèi)容被封裝到響應(yīng)報(bào)文的主體部分,其媒體類型的通過報(bào)頭“Content-Type”表示。由于該響應(yīng)報(bào)文的主體內(nèi)容是一個(gè)HTML文檔,所以“Content-Type”報(bào)頭表示的媒體類型為“text/html”。
1: HTTP/1.1 200 OK
2: Cache-Control: no-cache
3: Pragma: no-cache
4: Content-Type: text/html; charset=utf-8
5: Content-Encoding: gzip
6: Expires: -1
7: Vary: Accept-Encoding
8: Server: Microsoft-IIS/7.5
9: X-AspNet-Version: 2.0.50727
10: VTag: 791897542300000000
11: P3P: CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI"
12: X-Powered-By: ASP.NET
13: Date: Wed, 18 Jan 2012 07:06:25 GMT
14: Content-Length: 34237
15:
16: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
17: <html>…</html>
[1]超文本/超媒體(HyperText/HyperMedia):超文本是一份呈現(xiàn)文本內(nèi)容的電子文檔,其核心在于可以利用內(nèi)嵌的“超鏈接(Hyperlink)”直接訪問引用的另一份文檔。超媒體對(duì)超文本作了簡單的擴(kuò)展以呈現(xiàn)多媒體內(nèi)容(比如圖片、音頻和視頻等)。HTML文檔是我們常見的最為典型的超文本/超媒體文件。
[2] 除了采用這種4個(gè)層次的劃分方法之外,還具有另外兩種典型的劃分方式。其中一種在鏈路層下面添加一個(gè)基于物理網(wǎng)絡(luò)硬件的物理層,這種劃分方法與此沒有本質(zhì)的區(qū)別。另外一種則是將TCP/IP協(xié)議簇劃分為包括應(yīng)用層、表示層、會(huì)話層、傳輸層、網(wǎng)絡(luò)層、鏈路層和物理層在內(nèi)的7個(gè)層次。
參考資料:
[1] 《HTTP: The Definitive Guide》, By By David Gourley, Brian Totty, Marjorie Sayer, Anshu Aggarwal, Sailu Reddy
[2] 《RESTful Web Services》, RESTful Web Services
[3] 《A Brief Introduction to REST》,http://www.infoq.com/articles/rest-introduction
[4] 《TCP/IP Illustrated (Volumn 1: The Protocol)》, by W. Richard Stevens
我所理解的RESTful Web API [Web標(biāo)準(zhǔn)篇]
我所理解的RESTful Web API [設(shè)計(jì)篇]
聯(lián)系客服