diggbag

          BlogJava 聯(lián)系 聚合 管理
            0 Posts :: 13 Stories :: 6 Comments :: 0 Trackbacks

          接口抽象

          RESTful Web 服務(wù)使用標(biāo)準(zhǔn)的 HTTP 方法 (GET/PUT/POST/DELETE) 來抽象所有 Web 系統(tǒng)的服務(wù)能力,而不同的是,SOAP 應(yīng)用都通過定義自己個(gè)性化的接口方法來抽象 Web 服務(wù),這更像我們經(jīng)常談到的 RPC。例如本例中的 getUserList 與 getUserByName 方法。

          RESTful Web 服務(wù)使用標(biāo)準(zhǔn)的 HTTP 方法優(yōu)勢,從大的方面來講:標(biāo)準(zhǔn)化的 HTTP 操作方法,結(jié)合其他的標(biāo)準(zhǔn)化技術(shù),如 URI,HTML,XML 等,將會極大提高系統(tǒng)與系統(tǒng)之間整合的互操作能力。尤其在 Web 應(yīng)用領(lǐng)域,RESTful Web 服務(wù)所表達(dá)的這種抽象能力更加貼近 Web 本身的工作方式,也更加自然。

          同時(shí),使用標(biāo)準(zhǔn) HTTP 方法實(shí)現(xiàn)的 RRESTful Web 服務(wù)也帶來了 HTTP 方法本身的一些優(yōu)勢:

          • 無狀態(tài)性(Stateless)

          HTTP 協(xié)議從本質(zhì)上說是一種無狀態(tài)的協(xié)議,客戶端發(fā)出的 HTTP 請求之間可以相互隔離,不存在相互的狀態(tài)依賴。基于 HTTP 的 ROA,以非常自然的方式來實(shí)現(xiàn)無狀態(tài)服務(wù)請求處理邏輯。對于分布式的應(yīng)用而言,任意給定的兩個(gè)服務(wù)請求 Request 1 與 Request 2, 由于它們之間并沒有相互之間的狀態(tài)依賴,就不需要對它們進(jìn)行相互協(xié)作處理,其結(jié)果是:Request 1 與 Request 2 可以在任何的服務(wù)器上執(zhí)行,這樣的應(yīng)用很容易在服務(wù)器端支持負(fù)載平衡 (load-balance)。

          • 安全操作與冪指相等特性(Safety /Idempotence)

          HTTP 的 GET、HEAD 請求本質(zhì)上應(yīng)該是安全的調(diào)用,即:GET、HEAD 調(diào)用不會有任何的副作用,不會造成服務(wù)器端狀態(tài)的改變。對于服務(wù)器來說,客戶端對某一 URI 做 n 次的 GET、HAED 調(diào)用,其狀態(tài)與沒有做調(diào)用是一樣的,不會發(fā)生任何的改變。

          HTTP 的 PUT、DELTE 調(diào)用,具有冪指相等特性 , 即:客戶端對某一 URI 做 n 次的 PUT、DELTE 調(diào)用,其效果與做一次的調(diào)用是一樣的。HTTP 的 GET、HEAD 方法也具有冪指相等特性。

          HTTP 這些標(biāo)準(zhǔn)方法在原則上保證你的分布式系統(tǒng)具有這些特性,以幫助構(gòu)建更加健壯的分布式系統(tǒng)。

          安全控制

          為了說明問題,基于上面的在線用戶管理系統(tǒng),我們給定以下場景:

          參考一開始我們給出的用例圖,對于客戶端 Client2,我們只希望它能以只讀的方式訪問 User 和 User List 資源,而 Client1 具有訪問所有資源的所有權(quán)限。

          如何做這樣的安全控制?

          通行的做法是:所有從客戶端 Client2 發(fā)出的 HTTP 請求都經(jīng)過代理服務(wù)器 (Proxy Server)。代理服務(wù)器制定安全策略:所有經(jīng)過該代理的訪問 User 和 User List 資源的請求只具有讀取權(quán)限,即:允許 GET/HEAD 操作,而像具有寫權(quán)限的 PUT/DELTE 是不被允許的。

          如果對于 REST,我們看看這樣的安全策略是如何部署的。如下圖所示:


          圖 4. REST 與代理服務(wù)器 (Proxy Servers)
          REST

          一般代理服務(wù)器的實(shí)現(xiàn)根據(jù) (URI, HTTP Method) 兩元組來決定 HTTP 請求的安全合法性。

          當(dāng)發(fā)現(xiàn)類似于(http://localhost:8182/v1/users/{username},DELETE)這樣的請求時(shí),予以拒絕。

          對于 SOAP,如果我們想借助于既有的代理服務(wù)器進(jìn)行安全控制,會比較尷尬,如下圖:


          圖 5. SOAP 與代理服務(wù)器 (Proxy Servers)
          REST

          所有的 SOAP 消息經(jīng)過代理服務(wù)器,只能看到(http://localhost:8182/v1/soap/servlet/messagerouter, HTTP POST)這樣的信息,如果代理服務(wù)器想知道當(dāng)前的 HTTP 請求具體做的是什么,必須對 SOAP 的消息體解碼,這樣的話,意味著要求第三方的代理服務(wù)器需要理解當(dāng)前的 SOAP 消息語義,而這種 SOAP 應(yīng)用與代理服務(wù)器之間的緊耦合關(guān)系是不合理的。

          關(guān)于緩存

          眾所周知,對于基于網(wǎng)絡(luò)的分布式應(yīng)用,網(wǎng)絡(luò)傳輸是一個(gè)影響應(yīng)用性能的重要因素。如何使用緩存來節(jié)省網(wǎng)絡(luò)傳輸帶來的開銷,這是每一個(gè)構(gòu)建分布式網(wǎng)絡(luò)應(yīng)用的開發(fā)人員必須考慮的問題。

          HTTP 協(xié)議帶條件的 HTTP GET 請求 (Conditional GET) 被設(shè)計(jì)用來節(jié)省客戶端與服務(wù)器之間網(wǎng)絡(luò)傳輸帶來的開銷,這也給客戶端實(shí)現(xiàn) Cache 機(jī)制 ( 包括在客戶端與服務(wù)器之間的任何代理 ) 提供了可能。HTTP 協(xié)議通過 HTTP HEADER 域:If-Modified-Since/Last- Modified,If-None-Match/ETag 實(shí)現(xiàn)帶條件的 GET 請求。

          REST 的應(yīng)用可以充分地挖掘 HTTP 協(xié)議對緩存支持的能力。當(dāng)客戶端第一次發(fā)送 HTTP GET 請求給服務(wù)器獲得內(nèi)容后,該內(nèi)容可能被緩存服務(wù)器 (Cache Server) 緩存。當(dāng)下一次客戶端請求同樣的資源時(shí),緩存可以直接給出響應(yīng),而不需要請求遠(yuǎn)程的服務(wù)器獲得。而這一切對客戶端來說都是透明的。


          圖 6. REST 與緩存服務(wù)器 (Cache Server)
          REST

          而對于 SOAP,情況又是怎樣的呢?

          使用 HTTP 協(xié)議的 SOAP,由于其設(shè)計(jì)原則上并不像 REST 那樣強(qiáng)調(diào)與 Web 的工作方式相一致,所以,基于 SOAP 應(yīng)用很難充分發(fā)揮 HTTP 本身的緩存能力。


          圖 7. SOAP 與緩存服務(wù)器 (Cache Server)
          REST

          兩個(gè)因素決定了基于 SOAP 應(yīng)用的緩存機(jī)制要遠(yuǎn)比 REST 復(fù)雜:

          其一、所有經(jīng)過緩存服務(wù)器的 SOAP 消息總是 HTTP POST,緩存服務(wù)器如果不解碼 SOAP 消息體,沒法知道該 HTTP 請求是否是想從服務(wù)器獲得數(shù)據(jù)。

          其二、SOAP 消息所使用的 URI 總是指向 SOAP 的服務(wù)器,如本文例子中的 http://localhost:8182/v1/soap/servlet/messagerouter,這并沒有表達(dá)真實(shí)的資源 URI,其結(jié)果是緩存服務(wù)器根本不知道那個(gè)資源正在被請求,更不用談進(jìn)行緩存處理。

          關(guān)于連接性

          在一個(gè)純的 SOAP 應(yīng)用中,URI 本質(zhì)上除了用來指示 SOAP 服務(wù)器外,本身沒有任何意義。與 REST 的不同的是,無法通過 URI 驅(qū)動 SOAP 方法調(diào)用。例如在我們的例子中,當(dāng)我們通過

          getUserList SOAP 消息獲得所有的用戶列表后,仍然無法通過既有的信息得到某個(gè)具體的用戶信息。唯一的方法只有通過 WSDL 的指示,通過調(diào)用 getUserByName 獲得,getUserList 與 getUserByName 是彼此孤立的。

          而對于 REST,情況是完全不同的:通過 http://localhost:8182/v1/users URI 獲得用戶列表,然后再通過用戶列表中所提供的 LINK 屬性,例如 <link>http://localhost:8182/v1/users/tester</link>獲得 tester 用戶的用戶信息。這樣的工作方式,非常類似于你在瀏覽器的某個(gè)頁面上點(diǎn)擊某個(gè) hyperlink, 瀏覽器幫你自動定向到你想訪問的頁面,并不依賴任何第三方的信息。



          總結(jié)

          典型的基于 SOAP 的 Web 服務(wù)以操作為中心,每個(gè)操作接受 XML 文檔作為輸入,提供 XML 文檔作為輸出。在本質(zhì)上講,它們是 RPC 風(fēng)格的。而在遵循 REST 原則的 ROA 應(yīng)用中,服務(wù)是以資源為中心的,對每個(gè)資源的操作都是標(biāo)準(zhǔn)化的 HTTP 方法。

          本文主要集中在以上的幾個(gè)方面,對 SOAP 與 REST 進(jìn)行了對比,可以看到,基于 REST 構(gòu)建的系統(tǒng)其系統(tǒng)的擴(kuò)展能力要強(qiáng)于 SOAP,這可以體現(xiàn)在它的統(tǒng)一接口抽象、代理服務(wù)器支持、緩存服務(wù)器支持等諸多方面。并且,伴隨著 Web Site as Web Services 演進(jìn)的趨勢,基于 REST 設(shè)計(jì)和實(shí)現(xiàn)的簡單性和強(qiáng)擴(kuò)展性,有理由相信,REST 將會成為 Web 服務(wù)的一個(gè)重要架構(gòu)實(shí)踐領(lǐng)域。

          posted on 2011-10-21 11:05 哲同 閱讀(14010) 評論(1)  編輯  收藏 所屬分類: java相關(guān)

          Feedback

          # re: RESTful webservice 和 SOAP webserivce 對比及區(qū)別 2013-05-10 10:49 jnh1983
          The article is great, especially the picture. Thanks.  回復(fù)  更多評論
            

          主站蜘蛛池模板: 兴和县| 义乌市| 满城县| 托里县| 南投市| 宜宾市| 黔西| 新源县| 江永县| 阿瓦提县| 莱西市| 香港| 盐边县| 民勤县| 崇礼县| 唐海县| 正定县| 同江市| 内丘县| 同心县| 壤塘县| 信阳市| 会昌县| 兴隆县| 宜良县| 邵东县| 多伦县| 儋州市| 绩溪县| 阳原县| 邻水| 镶黄旗| 郓城县| 辛集市| 上虞市| 宝丰县| 邛崃市| 炉霍县| 雷山县| 广南县| 罗甸县|