REST的SOA(SOA with REST)概念
發展
1992年網站(Web Sites)是在Web瀏覽器和Web伺服器直接通過HTTP傳輸HTML。
2000年WS-* (Web Services)是在客戶端和伺服器之間基於HTTP傳輸SOAP XML格式的資料,服務端用WSDL來規定契約。
2007年RESTful (Web Services)是在客戶端和伺服器之間基於HTTP傳輸JSON、PO-XML、RSS格式的資料,服務端用WADL來規定契約。
Web services從哪來?
解決企業軟體標準化的問題
企業計算的互用性標準
一個提供訊息、描述、發現規範的分層架構
能夠快速從底層構建提供解決方案
工具可以將複雜性遮蔽
處理異構(Heterogeneity)
Web應用(Web Applications)與 企業計算(Enterprise Computing)
龐然大物(Big Web Services)
- 複雜難以理解(High perceived complexity)
- 標準化存在問題
- 鬥爭中(infighting)
- 缺乏架構的一致性(architectural coherence)
- 碎片化(fragmentation)
- 設計委員會(committee)
- 特性膨脹(feature bloat 主要提現在不斷新增的文件)
- 缺乏參考實現(reference implementations)
- 標準的標準(Standardization of standards (WS-I))
- 看似另一個CORBA?
- Web services的互用性真的存在?
- 我們真的需要採用XML來提升效能?
一個關於Web Services文件的不完全統計(http://www.tbray.org/ongoing/When/200x/2004/09/21/WS-Research)
正文目錄
什麼是REST?
RESTful的設計
WS-*與REST的比較
討論
前瞻
表述性狀態轉移(REpresentational State Transfer)
REST為Web定義了一個架構風格
它的四個原則可以用HTTP協議來實現
- URI資源識別(Resource Identification)
- 所有資源統一介面(Uniform Interface)
- GET(狀態查詢、冪等性、快取)
- POST(建立子資源)
- PUT(更新、狀態轉換)
- DELETE(刪除資源)
- 自解釋(Self-Describing),訊息的後設資料和多種資源表述
- 超連結(Hyperlinks),定義應用的狀態轉換和資源之間的關係
一個RESTful Web Service的例子
統一介面原則(CRUD的例子)
建立(POST《-》)——建立一個子資源
讀取(GET《-)——獲取當前資源的狀態
更新(PUT -》)—— 初始化或更新一個URI對應的資源狀態
刪除(DELETE)——清除一個資源(在一個URI失效之後)
統一資源識別符號URI(Uniform Resource Indentifier)是什麼?
- 因特網對於資源命名和標識的標準
例如:
http://tools.ietf.org/html/rfc3986
http——統一資源識別符號方案(URI Scheme)
://tools.ietf.org——授權(Authority)通常是一個主機名
/html/rfc3986——路徑(Path)
https://www.google.ch/search?q=rest&start=10#1
?q=rest&start=10——查詢(Query)
#1——片段(Fragment)
- REST並不擁護“好”的URI
- 在多數HTTP棧中URI的長度不能大於4Kb
什麼是“好”的URI?
URI的設計指南
- 名詞(Nouns)優於動詞(Verbs)
- URI保持簡短
GET /book?isbn=24&action=delete
DELETE /book/24
- 遵從位置通過引數傳遞的方案
REST URI對於客戶端透明的意思是它是由後續的連結提供,而不是通過客戶端自行建立
- 不要改變URI
- 真的需要改變時,用重定向實現(redirection)
注意:URI模板引入了客戶端和服務端的耦合
高階REST 和 低階REST
關於REST實現的最佳實踐有些區別(在本人實際工作中,很多技術實力雄厚的大型企業,對於REST最佳實踐的方案也基本可以歸為以下兩種,而第一種“低階”REST比較普遍)
低階REST(Low REST)
- 用HTTP GET實現冪等請求,其他所有請求都用POST(沒有HTTP PUT DELETE等其他方法)
- 響應格式(MIME Type)多種多樣(e.g. XHTML, application/json, application/xml)
高階REST(High REST)
- 推薦使用好的URI
- 充分使用4個動詞:GET、POST、PUT和DELETE(*)
- 響應體用(Plain Old) XML(**)
補充說明:
(*)有些防火牆或者HTTP的代理可能丟棄PUT/DELETE請求
(**)XML可以被RDF、JSON、YAML或者ATOM(ATOM存在很大的爭議)替代
資源表述的格式XML vs. JSON
XML | JSON(JavaScript Object Notation) |
—PO-XML | 為AJAX Web應用引入格式供(瀏覽器-Web伺服器通訊) |
—SOAP(WS-*) | |
—RSS,ATOM | |
半結構化的資料和標準的文字語法 | 文字語法支援序列化非迴圈的資料結構 |
工具:XML Schema,DOM,SAX,Xpath,XSLT,Xquery | 有很多語言支援(不僅僅JavaScript) |
每個人都可以解析它(不需要理解) | 不需要擴充套件 |
慢、臃腫 | JSON已經成為AJAX中的X而不是XML |
一個JSON的例子
REST 的優與劣
優勢(Strengths) | 劣勢(Weakness) |
簡單 —統一介面不可變更 |
混亂(區分high REST和low REST) |
HTTP/POX 無處不在 | 在前後臺系統設計中存在不匹配的情況(非同步訊息和事件驅動) |
無狀態/同步互動 | 除了HTTP/SSL不能實現其他的企業應用的風格(*) |
可擴充套件 | |
易於理解並採用(輕量級) —只需要一個瀏覽器,不需要WS中介軟體 |
對於合適的識別和定位所有應用中的資源時一個挑戰 |
樸素的方法(grassroot approach) | 缺乏標準(本人認為REST是一個設計風格而非標準) |
被所有的Web2.0應用採用 —85%的客戶都喜歡Amazon的RESTful API —Google不再支援SOAP/WSDL API |
語法和語義的描述是非正式的(面向使用者的) (本人認為這也恰恰是一個優勢) |
(*) 關於企業的應用風格(-ilities)參照文章http://www.cnblogs.com/richaaaard/articles/5006681.html
是否不能實現我們還有待探討
關於RESTful Web Services的設計方法
- 識別資源並暴露成服務(例如,年度風險報表,圖書分類,採購訂單,缺陷,調查投票等)
- 定義好的URL供定址
- 理解GET、POST、PUT、DELETE對於一個URI資源的意義
- 設計並記錄資源的表述
- 用超連結(hyperlinks)為資源關係建模
- Web伺服器實現與部署
- 用瀏覽器進行測試(當然這裡還有其他一些好的輔助測試工具,後面可以專門開文章探討)
一個簡單的Doodle API例子
- 建立一個投票
- 查詢一個投票
- 參加投票並建立一個新的子投票資源
- 更新一個一有投票(訪問控制頭沒有顯示)
- 當投票結果和決定產生後,投票可以將其刪除
更多的資訊可以檢視Doodle API: http://doodle.com/xsd1/RESTfulDoodle.pdf
(當然在RESTful下也有很多其他的API實現)
REST設計的相關小貼士
- 理解GET、POST、PUT
- GET 是一個只讀操作。它可以重複執行多次而不影響資源的狀態(冪等性),也可以被快取
- POST是一個讀寫操作,可以改變資源的狀態,也會讀伺服器產生影響
- PUT 是一個寫操作,但問題是如何正確的使用PUT?因為 PUT /resource/{id}可以被多個客戶端併發呼叫,如何保證資源{id}的唯一性?
- 多種表述形式的妥協(Content-Type)
- 通常客戶端可以提供自己可以處理的格式列表 Accept: text/html, application/xml, application/json
- 服務端則自己選擇最合適的響應格式200 OK Content-Type: application/json 服務端通常通過資源表述不同的字尾形式提供不同的內容格式(只是一個best practice而不是標準)
- GET /resource.html
- GET /resource.xml
- GET /resource.json
- 異常處理(Idempotent vs. Unsafe)
主要體現在HTTP的標準響應碼上
對於GET、PUT、DELETE這些冪等操作,可以執行多次而不會對服務端的狀態產生其他影響,可以在伺服器當機或者出現內部錯誤而恢復過後,重新發起這些請求。對於POST這種非冪等操作就需要在出現異常之後特殊處理,在有些場景下,它也可以被設計成冪等操作來實現:
B = GetBalance() // safe B = B + 200$ // local SetBalance(B) // safe
總而言之,對比WS-*和REST
就是一個蘋果和一個橘子的對比。一個是中介軟體互用性的標準,另一個是Web架構的風格。
那我們還是來比較一下SOAP和REST吧
- 先舉例
- 概念比較
- REST作為連結
- 技術性比較
- 服務的表述
- 安全
- 狀態管理
- 非同步訊息
舉一個RESTful Web 應用的栗子
同樣的場景下WS是這樣的
REST和SOAP最主要的區別在於
- 對於REST而言,Web是一個任何人都能訪問的資訊
—應用需要把它的資訊通過URI釋出到網路
- 對於WS而言,Web是任何傳輸的訊息
—應用可以與網路互動,但是他們處於網路之外
REST是一種連結方式
他們(REST vs. SOAP)是如何描述服務的呢?
REST | SOAP |
REST是基於人類可讀的文件,它定義了請求的URI和響應(XML,JSON) | 客戶端的stubs可以通過WSDL的描述用大多數語言生成 (實際上SOAP也是一種XML,也是可讀的) |
需要大量的測試和除錯,因為URI是手工建立的 (是否有相關工具) |
每個服務都根據自己的語法釋出自己的介面 |
我們為什麼需要強型別的訊息? (如果客戶端和服務端都很清楚傳輸的內容是什麼) |
強型別 |
WADL | WSDL1.1(整個開放埠對於GET和POST是統一的) |
XML 足夠了?(實際上有JSON、XML等其他) | WSDL2.0(更靈活,每個方法的GET or POST可選) |
REST和SOAP安全對比
REST | SOAP |
REST的安全就是HTTPs | SOAP的安全定義在WS-Security中 |
被證明的(SSL1.0 自1994) | XML加密 |
XML簽名 | |
—徹底的互用性沒有意義 | |
—效能? | |
點到點安全(認證、完整和加密) | 端到端安全,不需要HTTPs |
一直爭論的狀態還是無狀態
REST | SOAP |
顯性的狀態轉換 | 隱性的狀態轉換 |
—通訊是無狀態的 | —服務端可以保持狀態 |
—資源資料包含了有效的狀態連結 | —訊息只包含資料 |
—客戶端根據連結來獲取並維護狀態 | —客戶端根據服務端的狀態機邏輯來維護自己的狀態 |
Session技術 | Session技術 |
—Cookies(HTTP Headers) | —Session Headers(非標準) |
—URL Re-writing | |
—表格欄位隱藏 |
非同步可靠的訊息
- 對於REST來說,HTTP是一個同步的協議,但是它也可以模擬非同步訊息
POST /queue 202 Accepted Location: /queue/message/1230213 ____________________________ GET /queue/message/1230213 DELETE /queue/message/1230213
- SOAP訊息可以通過非同步協議傳輸(比如,JMS、MQ等)
- WS-Addressing可以用來定義獨立的傳輸點
- WS-ReliableExchange定義了一個可靠的傳輸協議(SOAP headers)
REST 和SOAP/WS*的相似點
REST | SOAP |
XML | O/XML 繫結 |
其他的方式JSON、YAML、RDF | |
XML Schema | 資料格式的契約需要和介面一起定義 |
HTTP | 儘管REST認為SOAP誤用了POST |
鬆耦合可擴充套件 | SOAP提供同步非同步方式 |
SOAP認為統一的介面不會改變 |
揭露所謂的祕密
- 許多REST的擁躉認為REST和Web service是不相相容的
- 實施上:SOAP和WSDL的新版本已經將Web services設計得更“RESTful”
- SOAP1.2
- Response MEP
- Web Method
- WSDL2.0
- HTTP繫結新增了操作級別(per-operation)對於GET、POST指定
- 增加對於safe/cacheable的屬性標籤
- 但是想讓RESTful完全使用Web services還是很困難
(然而市面上有些產品實際上可以支援他們的相相容)
總結和前瞻
- SOA可以用不同方式實現
- 關注架構如何解決問題以及這些相關標準的價值,而非具體架構和技術的盲從
- SOAP/WS-* 與 REST都有自己的優勢和適合的應用場景
- 未來會有融合兩種技術優勢的中介軟體技術出現(新SOAP和WSDL標準)
參考:
《SOA設計模式》 由Thomas Erl及其他供稿者合著,作為Thomas Erl關於面向服務計算叢書的一部分,於2009年1月由Prentice Hall出版,ISBN 0136135161,版權所有2009 SOA System Inc.。
Web Services and Service Oriented Architectures@2009 Cesare Pautasso