常見的三種Web服務架構

轉自http://www.cnblogs.com/bvbook/archive/2008/12/24/1360942.htmlhtml

相互競爭的服務架構程序員

The Competing Architecturesweb

咱們已經給出了「不一樣Web服務會有不一樣作法」的兩個主要問題,如今要據此對不一樣風格的Web服務進行分類了。根據個人研究,常見的Web服務架構主要有三種:REST式架構、RPC式架構和REST-RPC混合架構。下面依次對它們進行介紹。api

REST式、面向資源的架構ruby

RESTful, Resource-Oriented Architectures服務器

本書的主題是符合REST風格的Web服務架構——按照Roy Fielding博士論文裏的評判標準,它們能夠得到很高的得分。如今,雖然許多架構從技術上說是REST式的(注3),但我但願關注那些最適合Web服務的架構;因此,當我談及REST式Web服務時,我指的是那些具有Web特徵的服務——稱它們爲面向資源的(resource-oriented)。將在第3章經過一個真實的Web服務——Amazon S3(Simple Storage Service)來介紹面向資源的REST的基本概念,而後在第4章,向你逐個介紹REST的標誌特徵,並定義一種很是適合REST式Web服務的架構——面向資源的架構(Resource-Oriented Architecture)。架構

REST式架構意味着,方法信息(method information)都在HTTP方法(HTTP method)裏;面向資源的架構(ROA)意味着,做用域信息(scoping information)都在URI裏——兩者結合起來是很強大的。一個面向資源的REST式Web服務,經過HTTP請求的第一行(如「GET /reports/open-bugs HTTP/1.1」)就能基本瞭解客戶端要作什麼了,HTTP請求的其他部分只是具體細節而已。實際上,不少HTTP請求只要第一行就好了。若是HTTP方法跟方法信息對不上,那麼服務就算不上是REST式的;若是做用域信息不放在URI裏,那麼服務就不是面向資源的。雖然並不是只有這兩條要求,但它們是很好的經驗。函數

l   提供Atom發佈協議(http://www.ietf.org/html.char ters/atompub-charter.html)及其變型的服務,例如GData(http://code.google.com/apis/gdata/工具

l   Amazon S3(Simple Storage Service)(http://aws.amazon.com/s3post

l   Yahoo!提供的大部分Web服務(http://developer.yahoo.com/

l   許多其餘未採用SOAP的、只讀的Web服務

l   靜態網站

l   不少Web應用(尤爲是像搜索引擎這種只讀的)

每當談到非REST式架構或非面向資源的架構時,我都是有必定目的的。這一章將在Programmable Web的背景之下,對REST式Web服務加以全面考察。在第2章會提到一些真實的Web服務,並指出:不管一個服務是否正好符合我所推薦的架構,你均可以採用一樣的客戶端工具訪問它。在第10章,會就「應如何設計programmable web」這一久遠的話題發表觀點。

RPC式架構

RPC-Style Architectures

RPC式Web服務(RPC-style Web Service)一般從客戶端收到一個充滿數據的信封(envelope),而後發回一個一樣充滿數據的信封。RPC式架構意味着:方法信息和做用域信息都在信封(envelope)或報頭(headers)裏。具體採用哪一種信封,並不影響這裏的分類,不過HTTP是一種常見信封格式(畢竟,採用HTTP才稱得上是Web服務)。另外一種常見的信封格式是SOAP(把SOAP信封放在HTTP信封裏,在HTTP上傳送SOAP文檔)。各個RPC式服務採用本身的詞彙,就像計算機程序同樣(你每次寫程序,定義的函數名稱都不相同)。而REST式Web服務則相反,它們共用一套標準詞彙,即HTTP方法。REST式服務裏的每一個對象都具備統一的基本接口。

XML-RPC是最典型的RPC架構的例子。雖然目前XML-RPC主要是一種遺留協議(legacy protocol)了,但因爲它相對簡單,並且比較容易解釋,因此我仍是準備從它開始講起。示例1-11所示的Ruby客戶端用於訪問一個XML-RPC服務,該服務的做用是查詢具備統一產品代碼(Universal Product Code)的產品。

示例1-11:一個訪問XML-RPC服務的例子:根據UPC查詢產品

#!/usr/bin/ruby -w

# xmlrpc-upc.rb

 

require 'xmlrpc/client'

def find_product(upc)

   server = XMLRPC::Client.new2('http://www.upcdatabase.com/rpc')

   begin

      response = server.call('lookupUPC', upc)

   rescue XMLRPC::FaultException => e

      puts "Error: "

      puts e.faultCode

      puts e.faultString

   end

end

 

puts find_product("001441000055")['description']

# "Trader Joe's Thai Rice Noodles"

XML-RPC服務就像C語言同樣,你能夠調用一個帶參數(「001441000055」)的函數lookupUPC),並得到返回值。方法信息(函數名)和做用域信息(參數)都放在XML文檔(如示例1-12所示)裏。

示例1-12:一個描述XML-RPC請求的XML文檔

<?xml version="1.0" ?>

 <methodCall>

  <methodName>lookupUPC</methodName>

  <params>

   <param><value><string>001441000055</string></value></param>

 </params>

</methodCall>

這個XML文檔是放在信封裏傳給服務器的。這裏的信封(envelope)就是一個HTTP請求,它由HTTP方法、URI、報頭和實體主體等部分組成,其中實體主體就是上面的XML文檔(如示例1-13所示)。

示例1-13:一個包含了描述XML-RPC請求的XML文檔的HTTP信封

POST /rpc HTTP/1.1

Host: www.upcdatabase.com

User-Agent: XMLRPC::Client (Ruby 1.8.4)

Content-Type: text/xml; charset=utf-8

Content-Length: 158

Connection: keep-alive

 

<?xml version="1.0" ?>

<methodCall>

 <methodName>lookupUPC</methodName>

 ...

</methodCall>

上述HTTP信封裏的XML文檔,將隨你所調用方法的不一樣而有所變化,但HTTP信封的格式老是不變的。不管你對這個UPC查詢服務提什麼請求,URI老是http://www. upcdatabase.com/rpc,HTTP方法老是POST。簡單地說,XML-RPC服務未採用HTTP的不少特性;它只暴露一個URI(稱爲「端點」),而且該URI只支持一種HTTP方法——POST方法。

REST式服務爲不一樣的做用域信息暴露不一樣的URI;而RPC式服務通常爲每一個「文檔處理器」(用於打開信封,並把信封轉換爲軟件指令)暴露一個URI。咱們作個對比,假設上述UPC查詢服務被設計爲一種REST式架構的話,那麼其客戶端代碼將如示例1-14所示。

示例1-14:假想的示例代碼:一個REST式UPC查詢服務

require 'open-uri'

upc_data = open('http://www.upcdatabase.com/upc/00598491').read()

...

 

這裏,方法信息包含在HTTP方法裏(默認的HTTP方法是GET,它對應於示例1-13中的lookupUPC),做用域信息包含在URI裏。這個假想的服務暴露的URI不僅一個,每一個UPC代碼都有與之對應的URI。與示例1-13不一樣的是,這裏的HTTP信封是空的——它是一個沒有實體主體的HTTP GET請求。

另外一個RPC式服務的例子能夠參見示例1-8:Google SOAP API是一個採用SOAP做爲信封格式的RPC式服務。

較多采用或只採用HTTP POST的服務,多半是RPC式服務。雖然這不是絕對的,但至少能夠說明該服務沒有把HTTP方法用於表達方法信息。若是一個REST式服務過多地採用HTTP POST,那麼它就容易演變爲REST-RPC混合架構。

下面是一些知名的RPC式Web服務的例子:

l   全部採用XML-RPC的服務

l   幾乎全部的SOAP服務(這一點是有爭議的,本章後面的「Programmable Web涉及的技術」一節對此進行了探討)

l   少部分Web應用(一般是沒設計好的)

REST-RPC混合架構

REST-RPC Hybrid Architectures

這一術語是我創造的,它用於形容那些介於REST式架構與純RPC式架構之間的Web服務。這些服務一般是由那些對真實Web應用懂得比較多,但對REST理論不精的程序員們建立的。

咱們再次回顧一下這個調用Flickr Web服務時使用的URI:http://www.flickr.com/services/ rest?api_key=xxx&method=flickr.photos.search&tags=penguin。儘管URI裏包含「rest」字樣,但它顯然是一個採用HTTP信封的RPC式服務。另外一方面,它的做用域信息(「具備‘penguin’標籤的照片」)是放在URI裏的——從這一點看,它跟REST式面向資源的服務有點相像;不過它的方法信息(「搜索照片」)也被放在URI裏了,而前面說過,對於REST式服務,方法信息應該放在HTTP方法裏,其他部分所有做爲做用域信息。看來,這個服務只是把HTTP看成信封格式來用,而後按照本身的意願來放置方法信息和做用域信息——這是一個RPC式服務,鑑定完畢!

不過,咱們來看示例1-15。

示例1-15:一個向Flickr Web服務發HTTP請求的例子

GET services/rest?api_key=xxx&method=flickr.photos.search&tags=penguin HTTP/1.1

Host: www.flickr.com

這是當客戶端調用Flickr Web服務時發出的HTTP請求。這裏看上去,貌似方法信息是在HTTP方法裏的。 這個請求的意圖是獲取(GET)數據。 獲取什麼數據呢?一個搜索「具有‘penguin’標籤的照片」的結果列表。原先貌似方法信息的數據(「搜索照片」),如今看上去像是做用域信息(「photos/tag/penguin」)了。剛纔那個被鑑定爲RPC式的服務,如今呈現出REST風格了。

這是一個錯覺。一個RPC式服務採用普通老式HTTP(Plain Old HTTP)做爲信封格式,且方法信息和做用域信息恰好都在HTTP請求的URI路徑裏的話,就會產生這種錯覺。假如HTTP方法是GET,而且請求服務的意圖也是「獲取(GET)」信息的話,就會很難分辨方法信息是在HTTP方法裏,仍是在URI裏了。因此你會把一個RPC式服務的HTTP請求當作是REST式Web服務的HTTP請求。這個HTTP請求裏可能含有「method=flickr. photos.search」這樣的信息,但這個信息會被誤認爲是做用域信息(就像「photos/」和「search/」是做用域信息同樣)。這些RPC式服務,不經意間或多或少地帶着點REST式Web服務的特徵。它們只是把HTTP做爲一種信封格式來用,不過它們使用HTTP信封的方式可能恰好跟REST式服務的作法雷同。

許多隻讀的Web服務,儘管它們起初也許是按RPC風格設計的,但均可稱得上是徹底REST式和麪向資源的!可是,若是該服務容許客戶端修改數據的話,就會出現客戶端所使用的HTTP方法與真正的方法信息不一致的狀況——這樣它就不具有REST式服務的特徵了。像這樣的服務,我稱之爲REST-RPC混合服務。

舉個例子。即便客戶端的意圖是修改數據,Flickr Web API仍舊讓客戶端使用HTTP GET。若是要刪除一個照片,你須要向一個包含「method=flickr.photos.delete」的URI發出GET請求,儘管你的這個請求的意圖並非獲取(GET)數據,如我在第5章所講。Flickr Web API是一種REST-RPC混合架構:當客戶端經過GET方法獲取數據時,它是REST式的;當客戶端經過GET方法修改數據時,它是RPC式的。

一些知名的REST-RPC混合Web服務包括:

l   del.icio.us API

l   Flickr Web API

l   許多被說成是REST式架構的Web服務

l   大部分Web應用

從設計的角度來看,我認爲不會有人特地把服務設計爲REST-RPC混合架構。因爲HTTP工做方式的緣由,任何採用普通HTTP並暴露多個URI的RPC式服務,每每最終成爲REST式架構或混合架構。許多程序員按他們設計Web應用的方式來設計Web服務,並最終造成混合架構的服務。

混合架構的存在已經形成了很多混亂。從事Web應用設計的人容易設計出REST-RPC混合架構,並且他們經常聲稱這種混合架構是REST式架構——他們仍在以設計human web的方式來設計Web服務。已經有很多功夫花費在分辨REST式架構與其餘架構上了。我把「其餘架構」稱爲REST-RPC混合架構,這是衆多新詞中的一個,我認爲這個新詞是看待這些常見而使人困惑的服務最準確有效的方式。假如你知道它們的其餘稱呼(在寫本書的時候,「HTTP+POX」是最流行的),不妨繼續往下讀,後面我會用我本身的語言來解釋這些其餘術語。

相關文章
相關標籤/搜索