理解RESTful架構(gòu):網(wǎng)站即軟件
越來越多的人開始意識到,網(wǎng)站即軟件,而且是一種新型的軟件。
這種"互聯(lián)網(wǎng)軟件"采用客戶端/服務(wù)器模式,建立在分布式體系上,通過互聯(lián)網(wǎng)通信,具有高延時(shí)(high latency)、高并發(fā)等特點(diǎn)。
網(wǎng)站開發(fā),完全可以采用軟件開發(fā)的模式。但是傳統(tǒng)上,軟件和網(wǎng)絡(luò)是兩個(gè)不同的領(lǐng)域,很少有交集;軟件開發(fā)主要針對單機(jī)環(huán)境,網(wǎng)絡(luò)則主要研究系統(tǒng)之間的通信?;ヂ?lián)網(wǎng)的興起,使得這兩個(gè)領(lǐng)域開始融合,現(xiàn)在我們必須考慮,如何開發(fā)在互聯(lián)網(wǎng)環(huán)境中使用的軟件。

RESTful架構(gòu),就是目前***的一種互聯(lián)網(wǎng)軟件架構(gòu)。它結(jié)構(gòu)清晰、符合標(biāo)準(zhǔn)、易于理解、擴(kuò)展方便,所以正得到越來越多網(wǎng)站的采用。
但是,到底什么是RESTful架構(gòu),并不是一個(gè)容易說清楚的問題。下面,我就談?wù)勎依斫獾腞ESTful架構(gòu)。
一、起源
REST這個(gè)詞,是Roy Thomas Fielding在他2000年的博士論文中提出的。
Fielding是一個(gè)非常重要的人,他是HTTP協(xié)議(1.0版和1.1版)的主要設(shè)計(jì)者、Apache服務(wù)器軟件的作者之一、Apache基金會(huì)的***任主席。所以,他的這篇論文一經(jīng)發(fā)表,就引起了關(guān)注,并且立即對互聯(lián)網(wǎng)開發(fā)產(chǎn)生了深遠(yuǎn)的影響。
他這樣介紹論文的寫作目的:
"本文研究計(jì)算機(jī)科學(xué)兩大前沿----軟件和網(wǎng)絡(luò)----的交叉點(diǎn)。長期以來,軟件研究主要關(guān)注軟件設(shè)計(jì)的分類、設(shè)計(jì)方法的演化,很少客觀地評估不同的設(shè)計(jì)選擇對系統(tǒng)行為的影響。而相反地,網(wǎng)絡(luò)研究主要關(guān)注系統(tǒng)之間通信行為的細(xì)節(jié)、如何改進(jìn)特定通信機(jī)制的表現(xiàn),常常忽視了一個(gè)事實(shí),那就是改變應(yīng)用程序的互動(dòng)風(fēng)格比改變互動(dòng)協(xié)議,對整體表現(xiàn)有更大的影響。我這篇文章的寫作目的,就是想在符合架構(gòu)原理的前提下,理解和評估以網(wǎng)絡(luò)為基礎(chǔ)的應(yīng)用軟件的架構(gòu)設(shè)計(jì),得到一個(gè)功能強(qiáng)、性能好、適宜通信的架構(gòu)。"
(This dissertation explores a junction on the frontiers of two research disciplines in computer science: software and networking. Software research has long been concerned with the categorization of software designs and the development of design methodologies, but has rarely been able to objectively evaluate the impact of various design choices on system behavior. Networking research, in contrast, is focused on the details of generic communication behavior between systems and improving the performance of particular communication techniques, often ignoring the fact that changing the interaction style of an application can have more impact on performance than the communication protocols used for that interaction. My work is motivated by the desire to understand and evaluate the architectural design of network-based application software through principled use of architectural constraints, thereby obtaining the functional, performance, and social properties desired of an architecture. )
二、名稱
Fielding將他對互聯(lián)網(wǎng)軟件的架構(gòu)原則,定名為REST,即Representational State Transfer的縮寫。我對這個(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)化"中,省略了主語。"表現(xiàn)層"其實(shí)指的是"資源"(Resources)的"表現(xiàn)層"。
所謂"資源",就是網(wǎng)絡(luò)上的一個(gè)實(shí)體,或者說是網(wǎng)絡(luò)上的一個(gè)具體信息。它可以是一段文本、一張圖片、一首歌曲、一種服務(wù),總之就是一個(gè)具體的實(shí)在。你可以用一個(gè)URI(統(tǒng)一資源定位符)指向它,每種資源對應(yīng)一個(gè)特定的URI。要獲取這個(gè)資源,訪問它的URI就可以,因此URI就成了每一個(gè)資源的地址或***的識別符。
所謂"上網(wǎng)",就是與互聯(lián)網(wǎng)上一系列的"資源"互動(dòng),調(diào)用它的URI。
四、表現(xiàn)層(Representation)
"資源"是一種信息實(shí)體,它可以有多種外在表現(xiàn)形式。我們把"資源"具體呈現(xiàn)出來的形式,叫做它的"表現(xiàn)層"(Representation)。
比如,文本可以用txt格式表現(xiàn),也可以用HTML格式、XML格式、JSON格式表現(xiàn),甚至可以采用二進(jìn)制格式;圖片可以用JPG格式表現(xiàn),也可以用PNG格式表現(xiàn)。
URI只代表資源的實(shí)體,不代表它的形式。嚴(yán)格地說,有些網(wǎng)址***的".html"后綴名是不必要的,因?yàn)檫@個(gè)后綴名表示格式,屬于"表現(xiàn)層"范疇,而URI應(yīng)該只代表"資源"的位置。它的具體表現(xiàn)形式,應(yīng)該在HTTP請求的頭信息中用Accept和Content-Type字段指定,這兩個(gè)字段才是對"表現(xiàn)層"的描述。
五、狀態(tài)轉(zhuǎn)化(State Transfer)
訪問一個(gè)網(wǎng)站,就代表了客戶端和服務(wù)器的一個(gè)互動(dòng)過程。在這個(gè)過程中,勢必涉及到數(shù)據(jù)和狀態(tài)的變化。
互聯(lián)網(wǎng)通信協(xié)議HTTP協(xié)議,是一個(gè)無狀態(tài)協(xié)議。這意味著,所有的狀態(tài)都保存在服務(wù)器端。因此,如果客戶端想要操作服務(wù)器,必須通過某種手段,讓服務(wù)器端發(fā)生"狀態(tài)轉(zhuǎn)化"(State Transfer)。而這種轉(zhuǎn)化是建立在表現(xiàn)層之上的,所以就是"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。
客戶端用到的手段,只能是HTTP協(xié)議。具體來說,就是HTTP協(xié)議里面,四個(gè)表示操作方式的動(dòng)詞:GET、POST、PUT、DELETE。它們分別對應(yīng)四種基本操作:GET用來獲取資源,POST用來新建資源(也可以用于更新資源),PUT用來更新資源,DELETE用來刪除資源。
六、綜述
綜合上面的解釋,我們總結(jié)一下什么是RESTful架構(gòu):
(1)每一個(gè)URI代表一種資源;
(2)客戶端和服務(wù)器之間,傳遞這種資源的某種表現(xiàn)層;
(3)客戶端通過四個(gè)HTTP動(dòng)詞,對服務(wù)器端資源進(jìn)行操作,實(shí)現(xiàn)"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。
七、誤區(qū)
RESTful架構(gòu)有一些典型的設(shè)計(jì)誤區(qū)。
最常見的一種設(shè)計(jì)錯(cuò)誤,就是URI包含動(dòng)詞。因?yàn)?quot;資源"表示一種實(shí)體,所以應(yīng)該是名詞,URI不應(yīng)該有動(dòng)詞,動(dòng)詞應(yīng)該放在HTTP協(xié)議中。
舉例來說,某個(gè)URI是/posts/show/1,其中show是動(dòng)詞,這個(gè)URI就設(shè)計(jì)錯(cuò)了,正確的寫法應(yīng)該是/posts/1,然后用GET方法表示show。
如果某些動(dòng)作是HTTP動(dòng)詞表示不了的,你就應(yīng)該把動(dòng)作做成一種資源。比如網(wǎng)上匯款,從賬戶1向賬戶2匯款500元,錯(cuò)誤的URI是:
POST /accounts/1/transfer/500/to/2
正確的寫法是把動(dòng)詞transfer改成名詞transaction,資源不能是動(dòng)詞,但是可以是一種服務(wù):
POST /transaction HTTP/1.1
Host: 127.0.0.1
from=1&to=2&amount=500.00
另一個(gè)設(shè)計(jì)誤區(qū),就是在URI中加入版本號:
http://www.example.com/app/1.0/foo
http://www.example.com/app/1.1/foo
http://www.example.com/app/2.0/foo
因?yàn)椴煌陌姹?,可以理解成同一種資源的不同表現(xiàn)形式,所以應(yīng)該采用同一個(gè)URI。版本號可以在HTTP請求頭信息的Accept字段中進(jìn)行區(qū)分(參見Versioning REST Services):
Accept: vnd.example-com.foo+json; version=1.0
Accept: vnd.example-com.foo+json; version=1.1
Accept: vnd.example-com.foo+json; version=2.0
原文:http://www.ruanyifeng.com/blog/2011/09/restful.
【編輯推薦】