由SOAP說開去 - - 談談WebServices、RMI、RPC、SOA、REST、XML、JSON


引子:
關於SOAP其實我一直模模糊糊不太理解,這種模模糊糊的感覺表述起來是這樣:
  1. 在使用web服務時(功能接口),本來我就可以通過安卓中固有的http類(使用http協議),來發送http請求,並且解析返回的數據(一般是xml或者json),得到我要的結果
  2. 為什么還非得多此一舉使用soap呢,而且soap自己的介紹也說,它其實沒有發明技術,它其實就是http+xml
    1. 在安卓中使用soap的方法是:(下載第三方類庫),裝配一個soap請求體,使用soap包裝過的http類,通過http把請求體發送出去,然后解析返回的soap數據,取出里邊的xml數據,得到我要的結果
  3. 所以說人家好好的http,你平白無故在頭尾包裝一個soap(有點像加一個沒有作用的信封,因為HTTP本來就自帶信封),這不就是沒事收保護費嗎,不嫌煩么。(但其實我分析到這發現只是收了一個保護費,我表示還算可以接受吧,畢竟大家都交了)

於是我詳細查閱了網上的資料,結合自己的理解,歸納整理如下,引用部分過於零散,就未標示,還請諒解


 
要好好談SOAP,就必須從其源頭開始,它的源頭就是WebServices(Web服務)
 
1.Web服務
最早的軟件都是本地軟件,只運行在本地電腦上,直到網絡技術誕生它也只是利用網絡傳送資料,這之后網絡技術獨自發展網頁WEB自己發展了好多年,直到大家發現網絡技術不只是用來看看網頁,還可以把網絡技術更深地應用進本地軟件中,深入地跟本地軟件的功能結合,拓展本地軟件的功能,Web服務的概念就是在這種環境下興起的。
 
Web服務 簡單地說,,就是服務器如何向客戶端提供服務,現有的實現方式可以分為三類:
  1. SOA 面向服務的架構【面向消息】
  2. RPC  遠程過程調用的架構(remote procedure call)【面向方法】
  3. REST 表征狀態轉移的架構(Representational state transfer)【面向資源】
 
1.1.其他相關概念
RMI
  1. 使用java的程序員,對於RMI(RemoteMethod Invoke,遠程方法調用)一定不陌生,在java中,為了在分布式應用開發時,能夠方便調用遠程對象,java提供了RMI的API。在 RMI 中,遠程對象按照好象它是本地行事,客戶機應用程序會直接調用遠程對象存根上的方法,因此,調用起來就如本地對象一樣方便。RMI中封裝了對象和請求的網 絡傳送,使得異地的對象服務直接可用。
  2. 但RMI的使用必須是在能夠識別java代碼的環境下使用,即必須有JVM的支持。因此,他只適合在java程序間的對象通信。如果不在 Java 環境下工作,或者需要與非 Java 環境通信,那么SOAP、RPC、CORAR等都是可以的。.
  3. RPC(Remote Method Invocation,遠端過程調用) 與RMI的區別很明顯,相比於RMI直接獲取遠端方法的簽名,進行調用的方式,RPC使用的是C/S方式,發送請求到服務器,等待服務器返回結果。
  4. 通信方式:遠程對象按照好象它是本地行事.客戶機應用程序直接調用遠 程對象存根上的方法
  5. 優點:遠程對象按照好象它是本地行事,編譯期可以檢查錯誤
  6. 缺點:只能基於java語言。異常信息容易丟失。客戶機與服務器緊耦合。
 
2.SOA
SOA 是前幾年炒的很火的一個詞, 不亞於當前的 Cloud Computing , 如果說 RPC 是基於方法調用(method),那么 SOA 則是基於 消息, 基於方法調用通常會與特定的程序語言 耦合起來,而后者則與具體的實現語言無關, 所以在一定程度上得到大公司的支持
 
 
3.RPC
3.1總覽:
  1. RPC 即遠程過程調用, 很簡單的概念:像調用本地服務(方法)一樣調用服務器的服務(方法).
  2. 一般的過程是:向服務器發送一個過程調用的方法及其參數,得到服務器返回的方法執行的結果
  3. 通信方式:一般直接用底層的TCP,這樣更加快速,這是相比REST只能用HTTP的優勢,但它也可用HTTP
3.2.實現方式:
  1. XML-RPC
    1. XML-RPC是一個用XML消息執行RPC的簡單協議,服務請求使用XML來編碼,並通過HTTP POST發送,XML響應被嵌入HTTP響應主體。
    2. 在 Web服務發展的初期,XML格式化消息的第一個主要用途是,應用於XML-RPC協議。XML- RPC中,客戶端發送一條特定消息,該消息中必須包括名稱、運行服務的程序以及輸入參數。(相反, REST風格的請求卻不關心正在運行的程序是什么,它僅僅請求命名資源)
  2. JSON-RPC
    1. JSON-RPC是基於JSON格式的消息交換,JSON比XML更加輕巧,並且非常容易在頁面JS中使用,其他特點與XML-RPC類似
    2. XML-RPC , JSON-RPC的通信方式相同, 所不同的只是傳輸數據的格式,JSON格式更加易用
  3. SOAP協議
    1. XML- RPC只能使用有限的數據類型種類和一些簡單的數據結構。人們認為這個協議還不夠強大,於是就在使用HTTP的XML-RPC的基礎上發展出了更加強大的 SOAP協議,雖然其最初的定義是簡單對象訪問協議。之后,大家逐漸意識到SOAP其實並不簡單,而且也不需要必須使用面向對象語言,所以,現在人們只是沿用SOAP這個名稱而已,它經常被用於一些比較復雜的系統之上
    2. SOAP是在計算機之間交換信息的基於XML的協議,主要側重於通過HTTP傳輸RPC。它利用了XML的命名空間和XML模式(XML Schema),比XML-RPC更具適用性,能夠支持更多的類型及數據結構。
    3. 簡單的說,SOAP定義了如何將一個對象編碼成一種格式並通過一種協議傳送到另一個地方並還原的規范。
    4. 當然很多東西都是現成的,對象編碼后的格式是XML,傳輸的應用層協議是HTTP。 HTTP也並沒有定義如何在網絡上進行通信,其所使用的是TCP協議,TCP也沒有定義在路由之間如何傳輸包,那是IP協議。
    5. 但SOAP也不是什么新東西都沒有,譬如對象如何序列化成為XML格式,遠程過程調用(RPC)如何實現等,都是SOAP協議的一部分。
    6. XML- RPC只有簡單的數據類型集,取而代之,SOAP是通過利用XML Schema的不斷發展來定義數據類型的。同時,SOAP也能夠利用XML 命名空間,這是XML-RPC所不需要的。如此一來,SOAP消息的開頭部分就可以是任何類型的XML命名空間聲明,其代價是在系統之間增加了更多的復雜 性和不兼容性。
    7. 最 初,SOAP是作為XML-RPC的擴展而發展起來的,它主要強調的是,通過從WSDL文件中所獲得的方法和變量名來進行遠程過程調用。現在,通過不斷 進步,人們發現了更多的使用SOAP的方式,而不僅僅是采用“文件”方式(只是使用一個SOAP信封來傳送XML格式化文件)。無論如何,要掌握 SOAP,了解WSDL所扮演的角色是最根本的,看后邊的WSDL
    8. SOAP與XML-RPC對比
      1. XML-RPC是啟動Web服務最容易的方法,在很多方面比SOAP更簡單易用,但不同於SOAP的是,XML-RPC沒有相應的服務描述語法,這妨礙了XML-RPC服務的自動調用
      2. SOAP 有明顯的優越性:它非常適合異步通信和針對松耦合的客戶機和服務器。但這種好處會招致一些不利結果。必須做大量的運行時檢查,而且開發人員喪失了許多可以確保方法和參數是正確的編譯時便利。
      3. 可以認為SOAP是XML-RPC的高級版本,二者基於相同的原理:利用HTTP + XML封裝進行RPC調用
    9. 安全與SOAP
      1. 如果企業使用SOAP來傳送有價值的信息的話,那么,安全就是最重要的問題。由OASIS組織發起,計算機行業的領導者們已經聯合開發了一套標准,稱為WS-Security。這個標准對基本的SOAP通信做出了改善,以便能夠處理以下幾個問題:
        1. 消息機密性——由於攔截HTTP消息的方式非常多,因此,在請求和響應過程中,必須能夠對所有重要信息加密。很幸運,現在的加密技術非常先進,我們能夠對消息內容進行加密,以保證消息不被修改。
        2. 客戶和服務身份——必須能夠核實SOAP請求來源的身份。
 
3.3.其他相關概念
yar
yar是PRC的一個框架,類似webservice的,可以遠程調用方法,返回的數據不單單是字符串,可以是數組等類型。
比方說,當你的項目非常龐大的時候,有些公用的模塊就需要對外提供接口。
1、可以用curl方式調用,接口返回xml格式、或者json格式的字符串,調用方自己去解析。
2、可以用使用yar寫的方法,直接返回結果,就跟調用代碼本身的方法一樣,可以返回字符串、數組等格式。
 
Web服務描述語言-WSDL
WSDL(Web Services Description Language)是描述web服務的,是描述怎樣訪問web服務的。WSDL是用來描述SOAP的,換句話說,WSDL 文件告訴你調用 SOAP 所需要知道的一切。WSDL也是一段xml。現在各個語言對wsdl的支持都很成熟,可以根據同一份wsdl文件生成自己語言的客戶端。
為了創建一個用於描述Web服務的XML格式化文件,Web服務描述語言(WSDL)標准提供了足夠多的細節,以便能夠構建出客戶端代碼,從而訪問服務或者服務器端代碼以提供服務。一個服務的WSDL文件將會為你提供以下幾個方面的內容:
  1. 用於訪問服務的地址信息
  2. 用於傳送信息的傳輸協議(例如,通道數)
  3. 用於所有可使用功能的名稱和接口使用方法
  4. 在所有的請求和響應中所使用的數據類型
2001 年3月,W3C推出了WSDL 1.1版本用於討論,這並不是最終確定的規范。W3C Web服務描述工作組目前正在開發該規范的2.0版本,基本上已經到了尾聲。雖然,WSDL通常是用於特定的SOAP服務,但是,從理論說,它是完全可以 用於特定的REST風格的GET或者POST操作的。
能夠根據服務的WSDL描述來自動創建客戶端和服務器端代碼,支持這一功能的開發環境目前使用得很廣泛,以便能夠適用於Web服務器和Web服務客戶端的 不同程序設計語言。如果你使用Google搜索“SOAP IDE”的話,大概會出現上百萬條相關信息。也有這樣的工具,根據Java或C#對象來生成相應的WSDL和代碼。自動生成代碼也許能夠使你的開發效率更 高,但是離優化卻是越來越遠。
 
SOAP數據包結構解析
SOAP的消息被稱為一個SOAP Envelope,包括SOAP Header和SOAP Body。其中,SOAP Header可以方便的插入各種其它消息來擴充Web Service的功能,比如Security(采用證書訪問Web Service),SOAP Body則是具體的消息正文,也就是Marshall后的信息。
SOAP調用的時候,也就是向一個URL(比如 http://api.google.com/search/beta2 )發送HTTP Post報文(根據SOAP規范,HTTP Get報文也可被支持),調用方法的名字在HTTP Request Header SOAP-Action中給出,接下來就是SOAP Envelope了。服務端接到請求,執行計算,將返回結果Marshall成XML,用HTTP返回給客戶端。
 
 
4.REST
4.1.概念:
  1. REST並不是一種新興的技術語言,也不是什么新的技術框架,非協議也非規范 。准確來說說REST只是一種概念、風格或者約束,是一種針對網絡應用的開發方式, 是回歸HTTP本身的建議,可以降低開發的復雜性,提高系統的可伸縮性。
  2. REST是由Roy Thomas Fieding在他的博士論文《架構風格與基於網絡的軟件架構設計》中提出的一種架構思想。Roy Fielding是Apache基金會的合作創作者,同時也是HTTP、URI等Web基礎協議的主要設計者。從Roy Fielding的背景,我想大家就應該能了解到REST與Web之間的關系了吧。的確,在REST中我們關注技術實際上也只是URI、HTTP、Hypertext(超文本)而已。
  3. REST是中文翻譯為表征狀態轉移(英文:Representational State Transfer)是Roy Fielding博士在2000年他的博士論文中提出來的一種軟件架構風格。從字面意思來說,“表述”是很難理解是什么東西的?從論文上我們可以看到表述,一般指HTML文檔(包括json,xml等),jpeg等圖片資源。
  4. REST 采用Web 服務使用標准的 HTTP 方法 (GET/PUT/POST/DELETE) 將所有 Web 系統的服務抽象為資源,REST從資源的角度來觀察整個網絡,分布在各處的資源由URI確定,而客戶端的應用通過URI來獲取資源的表征。Http協議所抽象的get,post,put,delete就好比數據庫中最基本的增刪改查,而互聯網上的各種資源就好比數據庫中的記錄(可能這么比喻不是很好),對於各種資源的操作最后總是能抽象成為這四種基本操作,在定義了定位資源的規則以后,對於資源的操作通過標准的Http協議就可以實現,開發者也會受益於這種輕量級的協議。
  5. 談到REST大家的第一印象就是通過http協議的GET,POST,DELETE,PUT方法實現對url資源的CRUD(創建、讀取、更新和刪除)操作。這種形式的REST只是CRUD(增刪改查),從這個層面上,好像REST只是和RPC一個層面的東西,沒有什么了不起,其實這些都是對REST誤讀。也誤導大家實現REST時,特種注重GET,POST,PUT,DELETE方法的處理,包括一些所謂的REST框架,比如JBoss RESTEasy,Restlet Tomcat。究其原因是, REST提供了一組架構約束,當作為一個整體來應用時,強調組件交互的可伸縮性、接口的通用性、組件的獨立部署、以及用來減少交互延遲、增強安全性、封裝遺留系統的中間組件。其實從整個REST推導過程中可以了解到,REST沒有提及HTTP協議的任何方法,只是后期大家從REST的統一接口中擴展出這些操作概念。
 
4.1.推導REST
先從理論層次上我們看一下REST是怎么推導來的(參考論文第五章)
         Web架構背后的設計基本原理,能夠被描述為由一組應用於架構中元素之上的約束組成的架構風格。當將每個約束添加到進化中的風格時,會產生一些影響。通過檢查這些影響,我們就能夠識別出Web的約束所導致的屬性。然后就能夠應用額外的約束來形成一種新的架構風格,這種風格能夠更好地反映出現代Web架構所期待的屬性。通過簡述REST作為架構風格的推導過程,后面各節將會詳細描述組成REST風格的各種特定約束
     0.   從“空”風格開始。從架構的觀點來看,空風格描述了一個組件之間沒有明顯邊界的系統,這就是我們描述REST的起點。
  1. 客戶-服務器。客戶-服務器約束背后的原則是分離關注點。通過分離用戶接口和數據存儲這兩個關注點,我們改善了用戶接口跨多個平台的可移植性;同時通過簡化服務器組件,改善了系統的可伸縮性。
  2. 無狀態。這個約束導致了可見性、可靠性和可伸縮性三個架構屬性,但是無狀態並不是沒有缺點的,無狀態增加了在一系列請求中發送的重復數據(每次交互的開銷),可能會降低網絡性,正因為這個缺點,所以在REST風格中增加了緩存的考慮。
  3.  緩存,添加緩存約束的好處在於,它們有可能部分或全部消除一些交互,從而通過減少一系列交互的平均延遲時間,來提高效率、可伸縮性和用戶可覺察的性能。但是緩存還是有缺點的,如果緩存中陳舊的數據與將請求直接發送到服務器得到的數據差別很大,那么緩存會降低可靠性。注意這里的緩存並不是指MC,redis之類的緩存,而是在網絡代理中,比如proxy服務器上的緩存機制。
  4. 統一接口。使REST架構風格區別於其他基於網絡的架構風格的核心特征是,它強調組件之間要有一個統一的接口,為了獲得統一的接口,需要有多個架構約束來指導組件的行為。REST由四個接口約束來定義:資源的識別(identification ofresources)、通過表述對資源執行的操作、自描述的消息(self-descriptive messages)、以及作為應用狀態引擎的超媒體相關因素REST和其他概念關系。統一接口的雖然晦澀,但是它是REST風格核心特征,也是前面我們討論通過CURD方式操作資源的一種表現,也是我們最容易接觸感受到的一層,后面淘寶,微博,微信開放平台的開放接口,其實就是我們接觸這個平台的統一接口,評價一個開發平台是否REST的標准,也在於這個平台的設計者對統一接口的理解。
  5. 分層系統,分成系統風格通過限制組件的行為(即,每個組件只能“看到”與其交互的緊鄰層),將架構分解為若干等級的層。通過將組件對系統的知識限制在單一層內,為整個系統的復雜性設置了邊界,並且提高了底層獨立性。分層系統增加了數據處理的開銷和延遲,因此降低了用戶可覺察的性能對於一個支持緩存約束的基於網絡的系統來說,可以通過在中間層使用共享緩存所獲得的好處來彌補這一缺點。正因為REST風格有這樣的缺點,才會特意強調緩存的作用。
  6. 按需代碼,通過下載並執行applet形式或腳本形式的代碼,REST允許對客戶端的功能進行擴展,看似簡單的一種風格設計,其實對B/S貢獻最大的就是這個特性,現在ajax的底層其實就是按需代碼機制。
 
4.2.REST風格/約束:
Fielding 在他的論文中提出了一個RESTful應用應該具備的幾點約束。
  1. 每個資源都應該有一個唯一的標識
  2. 使用標准的方法來更改資源的狀態
  3. Request和Response的自描述
  4. 資源多重表述
  5. 無狀態的服務
Fielding 認為,只有具備了上面的約束的應用才能算是REST應用,其實現在許多所謂的REST應用或服務,其實並不能算是真正的REST應用,目前很多所謂的REST應用,其實只是RPC而已。出現這樣的情況很正常,因為RPC更符合一般程序員的思維。
之后這幾個約束被表述為:
  1. Client–server C/S結構 (這是Internet服務的一個基本特征)
  2. 無狀態性
  3. 能夠利用Cache機制增進性能 (想起了瀏覽器?)
  4. 分層系統 (想起了無數的架構?)
  5. 統一的接口規范分層交互
  6. 隨需代碼 - Javascript (可選,其實是一種擴展性的要求)
 
看了這幾個特征后,你想起了什么? 你可能會破口而出:HTTP
HTTP是WWW的最核心的協議, 它將簡單的分布於世界各個角落的資源都統一起來, 統一的地址, 簡單的方法, 和一定數量的表達方式.(你可能對這三點描述很模糊,請go ahead).
REST 的三個要素就是是 唯一的資源標識, 簡單的方法 (此處的方法是個抽象的概念), 一定的表達方式.
REST 是以 資源 為中心, 名詞即資源的地址, 動詞即施加於名詞上的一些有限操作, 表達是對各種資源形態的抽象.
以HTTP為例,名詞即為URI(統一資源標識), 動詞包括POST, GET, PUT, DELETE等(還有其它不常用的2個,所以 整個動詞集合是有限的), 資源的形態(如text, html, image, pdf等)
 
根據以上的描述,我們其實發現HTTP是一種典型的REST風格,這也難怪,在1994年提出REST風格時,REST被稱作“HTTP對象模型”,但是那個名稱常常引起誤解,使人們誤以為它是一個HTTP服務器的實現模型。這個名稱“表述性狀態轉移”是有意喚起人們對於一個良好設計的Web應用如何運轉的印象。反過來看HTTP就是REST的具體實現。在一個REST風格中,我們能夠感受到的就是統一接口的數據,這些數據包括所以,當我們開發一個web服務時,比如一個網站,由於使用了HTTP(HTTPS)協議,其實就是一種REST風格,但是在這個REST風格中我們着重處理的是兩點
       1:URI,即所謂的資源,網站的uri設計
       2:統一接口,即所謂的PUT,GET,POST,DELETE方法
雖然我們的網站是REST的風格的,但是由於統一接口設計的不好,導致我們網站在訪問請求時,效率低下,以及可擴展性差。在深入淺出REST中,作者總結了五條關鍵原
        1:為所有“事物”定義ID
        2:將所有事物鏈接在一起
        3:使用標准方法
        4:資源多重表述
        5:無狀態通信
其中前四條就是對統一接口中的數據元素,第一二條講的就是uri,第三四條講的是控制數據。第五條無狀態通信,這個需要特別說明下,無狀態通信是指服務器和客戶端通信是無狀態的,假如我們的系統中使用Session保存客戶端狀態,這種情況就是非無狀態通信,是一種unREST的方式。但是應用本身是有狀態的,比如用戶登錄前后,就是應用狀態的變化。
 
 
4.3.REST與WEB
Fielding指出,使用且符合代表性狀態傳輸(REST)設計約束的 Web 上部署的組件,可以充分利用 Web 的有用特性,萬維網(World Wide Web)才能夠達到最佳的工作效果。可以這樣理解REST——當一個瀏覽器得到並且顯示構成HTML頁面的各個元素時,它正在獲取資源的當前狀態的表現形式。在Fielding的博士論文中,他列舉了REST風格的設計約束,並且解釋了為什么這些約束能夠充分利用Web 的有用特性,使其達到最佳狀態,以及這些約束的關鍵所在。同時,在論文中,他也包含了一些關於REST和某些目前的Web風格之間 “不符合”的討論,以及這些Web風格是如何導致設計無法利用Web特性的。
Fielding認為,對於使用HTTP承載應用程序協議穿越防火牆,XML-RPC 和SOAP所采用的方式是“從根本上被誤導的概念。”它們所采用的方式違背了設立防火牆的概念,結果是,防火牆廠商為了保護系統需要偵察出所承載的協議。由於大多數SOAP應用程序使用HTTP都是為了穿越防火牆,因此,你可以發現REST與SOAP之間的沖突是從哪里開始的。Fielding認為,如果你打算使用HTTP的話,就應該與充分利用HTTP本身的含義。
REST風格強調,通過有限的操作或者是“動詞”以及一個組件之間的標准接口,也就是HTTP協議提供的借口,來提升客戶與服務之間的交互。通過為每一個資源分配其自己的URL,來實現靈活性,REST可以調用包含上百個URI的資源類型的客戶,其中的關鍵是REST能夠給你無限多的“名詞”。REST使用HTTP的動詞——簡單的良定義操作集:POST, GET, PUT,DELETE進行請求和響應,從而避免了歧義。舉個例子,GET只能夠簡單地返回資源的表現形式,而不能夠創建任何其他的內容。
在Web發展的初期,由於人們都在試驗通過收集各種不同來源的元素,從而把Web應用程序融合在一起,有大量這種Web服務的不成熟探索的例子——從HTTP頁面中解析信息,用於頁面創建者沒有計划到的用途。這種“屏幕抓取”的Web類比表明,REST風格的方法是先於那些更加復雜的Web服務而出現的。
 
4.4.規划REST服務
在InfoQ上有一篇很好的文章來介紹如何規划REST服務《如何獲取(GET)一杯咖啡——星巴克REST案例分析》,估計大家看完這篇文章,應該對如何規划REST服務會有更深的認識。
當我們要規划REST服務的時候,其中最關鍵的概念是“資源”。
資源是什么呢?廣義上講,任何事物只要有用,它就是資源。狹義的講(在Web環境中),它是一個可以存放、連接在計算機上,可以通過比特流進行操控的實體。一個實體若要成為資源,它必須有一個URI。在這里URI包含了兩重含義:1)它是該資源的名稱 2)它是該資源的地址。
在規划URI的時候,有幾點希望大家能夠注意一下:
  1. 一個URI標識一個資源,但是一個資源可以被多個URI標識。
  2. 資源也是有層次的,這個層次應該在URI上充分的體現出來。
  3. 在規划URI的時候,需要定義一些團隊內部確認的關鍵字或符號,這些關鍵字或符號是有特殊意義的,不能隨便使用。
  4. 需要有一個URI定義的文檔,以備以后的查詢和維護。
  5. 可以使用URI Template來描述URI的定義。如何使用URI Template請看看這篇文章。
當我們定義好資源之后,接下來要做的事情就是定義操作資源的方法以及資源的表述格式了。
使用HTTP提供的基本方法來對資源進行操作,一般的操作定義如下:POST(創建資源)、GET(獲取資源)、PUT(修改資源)、DELETE(刪除)。它們正好對應了CRUD。
對資源的表述,一般的選擇會是XML,但是我更加推薦使用JSON來表述資源。在網絡中的傳輸量小,而且也便於JavaScript解析,同時使用其他語言解析也是非常方便的事情。不過,最關鍵的還是占用更少的資源,讓同樣的資源能夠服務於更多的人。
 
 
4.5.一個簡單的REST舉例
  假設我們希望一個Web服務暴露一部分目錄,從這個目錄中,用戶將能夠得到一些描述、圖片、安裝指令等等。為了得到數字“n1996-01”的描述,用戶需要格式化一個GET請求,類似於下面的這個URL: http://company.com/catalog/description/n1996-01
  在處理這個請求時,“/catalog”將映射到一個服務中,之后,通過該服務對“description/n1996-01”進行解釋,從而 定位資源。在創建響應時,服務需要使用內容類型(Content-Type)的頭文件來指定返回格式。在這種情況下,假定返回格式是HTML或者XML, 客戶端能夠使用它來控制頁面的布局。如果要得到圖片,那么這個請求將對“/catalog/picture/n1996-01”進行尋址,返回的響應將是 圖片內容類型(Content-Type)。
 
 
4.6.REST的應用場景:
其實,我們經常容易犯的一個錯誤是:當我們了解了一個新的技術,就會用這個技術來解決所有的問題。有一句諺語是這么來說的:“在錘子的眼里,所有的東西都是釘子”,其實REST也只是我們工具箱里面的其中的一個工具而已,希望不要把它當做我們唯一的工具。下面,我們就來聊聊適合使用REST的應用場景和不適合使用REST的應用場景。
在我看來,REST最適合的應用場景是需要對外暴露服務的情況。此時,我們可以充分利用REST的自描述、無狀態、唯一標識等特性來提供清晰、友好的API;此外,目前Jesery、RESTEasy等JAX-RS框架也提供了OAuth的支持,基本上能夠保證服務安全。
最不適合的應用場景是對性能要求高的系統內部的服務調用,在這種情況下使用REST的話,那么REST所有的特性都會變成拖累。這個時候,還是需要選擇更底層的通信協議和方式會更好一些,比如ICE。這樣的錯誤,我曾經犯過,后來通過很長時間的努力才慢慢的將這個錯誤改過來。
 
4.7.RPC與REST的比較
  1. RPC是以動詞為中心的,REST是以名詞為中心的,此處的動詞指的是一些方法,名詞是指資源。REST強調資源(名詞)有統一的接口以此來對它們尋址,而RPC強調過程(動詞)有統一的接口來激發它們
    1. 你會發現,以動詞為中心,意味着,當你要需要加入新功能時,你必須要添加更多的動詞, 這時候服務器端需要實現 相應的動詞(方法), 客戶端需要知道這個新的動詞並進行調用.
    2. 而以名詞為中心, 假使我請求的是 hostname/friends/, 無論這個URI對應的服務怎么變化,客戶端是無需 關注和更新的,而這種變化對客戶端也是透明的.
    3. 一個基於RPC的架構,動詞數量是 沒有限制的。REST說,我們使用四個動詞——非常熟悉,HTTP標准的GET、POST、PUT以及DELETE——來進行請求和響應,REST使用資 源尋址來處理其可變性
  2. 至於其它的區別,如對實現語言的依賴, 耦合性等,這些都是上面提到的這個根本區別所衍生的
  3. REST回歸HTTP最初的設計;RPC僅僅只是把HTTP作為傳輸協議來使用。
  4. REST是由超文本驅動的;RPC是由方法驅動的。
  5. REST強調HTTP通信的語義可見性,通過消息頭和標准的HTTP方法來體現;RPC把語義封裝在HTTP消息體中。
如何選擇?
根據筆者自己的經驗和心得, 建議 能夠使用REST就盡量使用REST, 主要基於下面幾個考慮:
  1. 擴展性
  2. 松耦合(意味着,不用強制要求客戶端去更新相應的代碼)
  3. 客戶端實現語言無關
  4. 性能
  5. 安全性(例如HTTPS)
當然上述的幾點也並非 RPC 都不滿足,不過相對而言, REST 更加清晰和簡潔, 再輔以 JSON 相應的服務會在性能和穩定性(簡單通常意味着robust)方面有很大的提高.
 
總體上,因為REST模式的Web服務與復雜的SOAP和XML-RPC對比來講明顯的更加簡潔,越來越多的web服務開始采用REST風格設計和實現。例如,Amazon.com提供接近REST風格的Web服務進行圖書查找;雅虎提供的Web服務也是REST風格的。REST對於資源型服務接口來說很合適,同時特別適合對於效率要求很高,但是對於安全要求不高的場景。而SOAP的成熟性可以給需要提供給多開發語言的,對於安全性要求較高的接口設計帶來便利。所以我覺得純粹說什么設計模式將會占據主導地位沒有什么意義,關鍵還是看應用場景,正是那句老話:適合的才是最好的
同時很重要一點就是不要扭曲了REST現在很多網站都跟風去開發REST風格的接口,其實都是在學其形,不知其心,最后弄得不倫不類,性能上不去,安全又保證不了,徒有一個看似象摸象樣的皮囊。
 
4.8.soap與REST比較:
  1. REST依賴一套簡單的“動詞”,把所有的復雜性都轉移到了指定資源的“名詞”中。與此不同,SOAP卻有一套相當復雜的XML格式化命令和數據傳輸選項。
  2. 非常重要一點是,REST是需要請求HTTP的,與其相比,SOAP更具優勢,SOAP消息可以由所有能夠處理Unicode文本的傳輸方式來傳 送,很可惜,這一點通常不被人們所認可。事實是,由於HTTP穿透防火牆的便捷性,以及開發商們對Web非常熟悉,因此,人們還在繼續強調着HTTP傳 輸。
  3. 在 開發人員的意識里,對於Web服務的開發而言,REST和SOAP風格各有千秋。SOAP擁有更為詳盡的標准化成果和開源工具。除此之外,現在,有許多 集成開發環境能夠在現有代碼的基礎上,依據接口方法自動生成SOAP。如果你需要使用WSDL來發布你的服務,或者你需要一些安全功能如消息簽名和加密, 那么,SOAP能夠確保消息的安全性。另一方面,如果你希望使用簡單接口來公布一些信息,而不需要繁瑣的處理過程,那么,REST也許是最佳選擇。
  4. 眾多從事Web服務的軟件設計師們認為SOAP過度復雜,於是,類似eBay和Google的服務都采用了REST風格的約束來暴露其大量數據。
  5. 甚至可以有RESTful SOAP。盡管還網上沒人提到RESTful SOAP,但我覺得這在理論上是沒問題的
造成SOAP和REST放在一起討論是因為,網絡上很多工程師把REST風格和REST的實現混淆了。REST的概念比較寬泛,本身如果符合1)Client–server, 2)Stateless, 3)Cacheable, 4)Layered system, 和5)Uniform interface這幾個主要的限制,就是RESTful的設計。同時呢,由於HTTP是一個很容易滿足stateless, cacheable,uniform interface的protocol,所以實際上REST被默認就是用HTTP來實現,很多人耳熟能詳HTTP的verb如何對應到resource的CRUD,仿佛也成了REST風格本身的死規定。我認為其實不然,以HTTP中的PUT為例,如果用PUT來實現resource的update,那么就必須要保證idempotent,每次傳給server的信息,必須是resource的全部信息,不能作partial update。不難發現,用PUT來實現update,其實是在REST的constraint上又加上了HTTP的一些限制。如果我們放棄PUT的constraint,采用POST來實現update,則partial update是可以的。緊接着就由一個問題,既然PUT被POST替代,那么我們是否可以用POST來代替GET和DELETE呢?筆者認為應該沒問題,一個很現實的例子,如果browser不支持DELETE,用POST來work around是很常見的。
okay, 再來看看SOAP,很多在HTTP上實現的SOAP協議就是用POST來實現的 (wikipedia里SOAP的一個sample http://en.wikipedia.org/wiki/SOAP#Example_message)
因此,當我們使用HTTP POST來實現REST,再加上XML的數據傳輸格式,其實我們就是在SOAP上面實現了RESTFul的"風格"(盡管還網上沒人提到RESTful SOAP,但我覺得這在理論上是沒問題的)。
與RESTful SOAP相對的一個例子,很多基於Rails的website(並非說Rails不好,Rails大行其道使得REST風行,故舉例)URL風格是/callSomeMethodWithArgumentA, /callSomeMethodWithArgumentB,非常長,不uniform,不滿足REST的限制,這些route都是不RESTFul的,我們可以稱之為non-RESTful HTTP
長話短說,本人認為SOAP協議和REST架構風格是兼容的。雖然,約定俗成,REST的具體實現一般采用HTTP,且充分利用HTTP verb的不同特性,從而形成了一些約定俗稱的范式,但這種實現本身不是REST"風格"的核心。
 
目前,大部分Web開發者似乎都了解REST——一種采用標准URI進行調用的方案。REST很容易理解,而且只要是支持HTTP/HTTPS的客戶端/服務器就支持它。你可以用HTTP GET方法來執行命令。所以,開發者們感受到的REST的優勢是:開發簡單、只需依托現有Web基礎設施、以及學習成本低。
然而,SOAP作為一種古老的Web服務技術,短期內還不會退出歷史舞台。而且,隨着SOAP 1.2的出現,SOAP印象中的一些缺點已得到改進,采納率和易用程度也都得到提高。另需注意的是,從W3C SOAP 1.2版開始,SOAP這一縮寫不再代表Simple Object Access Protocol(簡單對象訪問協議),而是僅僅作為協議名稱而已。
相對REST而言,SOAP 1.2多出一些開銷,不過這些開銷也帶來了一些好處。首先,SOAP在三個方面離不開XML(Extensible Markup Language,可擴展標記語言):SOAP信封(envelope)是基於XML的,它定義了消息里有什么以及如何處理它;一套用於數據類型的編碼規則;過程調用和響應的規划。SOAP信封由傳輸協議(HTTP/HTTPS)發出,RPC(Remote Procedure Call,遠程過程調用)得到執行,然后一個XML文檔隨SOAP信封返回。
需要注意的是,基於“通用”傳輸協議是SOAP的一個優點。REST目前基於HTTP/HTTPS;而SOAP可支持任何傳輸協議,從HTTP/HTTPS到SMTP(Simple Mail Transfer Protocol,簡單郵件傳送協議),甚至JMS(Java Messaging Service,Java消息傳遞服務)。不過,由於XML較為冗長且解析費時,因此采用XML也成為一個弊端。
不過,對Web開發者來說的好消息是,目前上述兩種方案都是行之有效的方案。REST和SOAP都能解決許多Web方面的問題與挑戰,而且在許多情況下,它們各自都能滿足開發者的要求,也就是說可互換使用。
但很多人不知道,這兩種技術可以混合搭配使用。REST很好理解,且極易上手;不過由於它缺乏標准,因此只被看作是一種架構方法。與之相比,SOAP是一個工業標准,它具備良好定義的協議,以及一套良好確立的規則,在大型和小型系統中均有采用。
因此,REST的適用場合包括:
有限的帶寬和資源 別忘了返回的結構可以采用(由開發者定義的)任何格式。另外,由於REST采用標准的GET、PUT、POST和DELETE動詞,因此可被任何瀏覽器所支持。除此以外,REST還可以使用為目前大多數瀏覽器支持的XMLHttpRequest對象,這為AJAX增色不少。
完全無狀態的操作 對於那些需多步執行的操作,REST並非最佳選擇,采用SOAP更合適。但是,如果你需要無狀態的CRUD(Create/Read/Update/Delete,創建/讀取/更新/刪除)操作,那么應采用REST。
緩存考慮 若要利用無狀態操作的特性,使得信息可被緩存,那么REST是很好的選擇。
以上已經覆蓋很多方案了,那么,為什么還要考慮SOAP呢?正如前述,SOAP比較成熟而且是經過良好定義的,具有完整的規范。而REST只不過是一種方法,對開發未作任何規約;因此,假如你遇到以下場合,那么SOAP是最佳選擇:
異步處理與調用 如果你的應用需要確保可靠性與安全性,那么請采用SOAP。SOAP 1.2為確保這種操作補充定義了WSRM(WS-Reliable Messaging)等標准。
形式化契約 若提供者/消費者雙方必須就交換格式取得一致,那么采用SOAP更合適。SOAP 1.2為這種交互提供了嚴格的規范。
有狀態的操作 如果應用需要上下文信息與對話狀態管理,那么應采用SOAP。SOAP 1.2為此補充定義了WS-Security、WS-Transactions和WS-Coordination等標准。相比之下,REST方法要求開發者自己來實現這些框架性工作。
正如你所看到的,REST和SOAP各自有其用武之地。它們在安全性和傳輸層等方面有着自己的潛在問題,不過它們都能完成任務,而且在許多情況下,它們都豐富了Web的技術手段。因此,就這一論題,其實最好的原則就是靈活性原則;因為至少在現今的Web開發中,無論面對何種問題,Web開發者們總有辦法運用好這兩種技術中的一種。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM