上個月,我在Skillsmatter參加了一個關于RESTful微服務快速進階的培訓課程,。課程著重探討了REST API在web應用和微服務交互方面起到的作用,。對我來說,這個課程給我最大的收獲是讓我更好地理解REST,,以及它的優(yōu)點和不足,。過去我大部分工作是在移動技術領域,也就是web API的調用端,。我過去所調用的大部分API被認為是RESTful的,,不過現在我對RESTful有了更深的理解,我敢說那些API里有99%都算不上RESTful,。 定義REST是“呈現狀態(tài)轉移(REpresentational State Transfer)”的縮寫,。或許可以這樣來定義它:一種API的架構風格,,在客戶端和服務端之間通過呈現狀態(tài)的轉移來驅動應用狀態(tài)的演進,。 約束要讓應用RESTful化,需要遵循以下約束,。遵循了這些約束的分布式系統,,就會擁有如下非功能屬性:性能,伸縮性,,易用性,,擴展性,可見性,,可移植性和可靠性,。 CS模式CS模式通過分離客戶端和服務器端的關注點,讓客戶端不再關注數據的存儲問題,,從而提高客戶端代碼的可移植性,。另一方面,服務器端不再關注用戶界面和用戶狀態(tài),,從而變得更簡單,,提高了伸縮性。服務器端跟客戶端可以獨立開發(fā),,只要它們都遵守契約,。 無狀態(tài)客戶端上下文在多個請求之間是絕不會保存在服務器上的。每個請求必須包含必要的信息。無狀態(tài)的服務器通過快速釋放資源和簡化實現提高了可伸縮性,??煽啃允沟脧木植渴≈谢謴妥兊萌菀住:苊黠@,,監(jiān)控系統不必通過考慮單個請求來判斷請求的性質,。 無狀態(tài)服務器的一個缺點是降低了網絡性能,因為所有需要的數據必須在每次請求中發(fā)送,。 可緩存REST應用程序是web系統,,因此客戶端和中間層可以緩存響應。響應必須被定義為可緩存或不可緩存的,,以防客戶端重復使用舊數據導致降低可靠性,。如果緩存中的陳舊數據與已生成的請求的數據顯著不同,則由服務器處理請求,。緩存可以消除一些客戶端和服務器之間的交互,,這就提升了可伸縮性、效率和通過減少平均延遲達到的用戶可感知的性能,。 統一的接口使用統一的接口降低了系統復雜度和耦合度,,讓系統的不同部分可以獨立演化。稍后會解釋URI,,資源和超媒體是如何通過生成標準接口來提升用戶交互可見性,,降低系統復雜度,促進系統組件獨立演化的,。但是我們需要在效率方面做出妥協,,畢竟消息是通過標準格式傳輸的,并不能滿足所有應用對消息格式的要求,。 分層的系統分層系統通過約束組件的行為來降低系統復雜度,,組件不能越過它們的媒介層去訪問其它層。通過組件的阻斷來保持層間的獨立性,。遺留的組件可以被封裝成新的層,,不讓舊的客戶端訪問。媒介層可以通過負載均衡來提升伸縮性,。分層系統存在的主要不足,,是它給數據處理增加了一些額外的開銷,增加了延遲,,對用戶體驗有所影響,。 按需編碼REST允許客戶端通過下載執(zhí)行腳本來擴展它們的功能,簡化了客戶端,,也提升了擴展性,。但這同時也降低了可見性,,所以這個約束不是必須遵循的。 元素REST提供了以下幾種元素來構建無狀態(tài),,可伸縮的web API,。
HTTP - 文本傳輸協議REST一般使用HTTP作為它的傳輸協議,因為HTTP提供了一些很好用的特性,,如HTTP動詞,,狀態(tài)碼和頭部信息。 HTTP動詞HTTP并沒有定義很多動詞來描述web服務中可能出現的行為,,它只用了一個標準動詞集合來處理各種相似情況,,從而讓API變得更直觀,。每個動詞通過兩種屬性的組合來滿足不同的場景需求,。
GET用來從服務器端讀取狀態(tài)。這個操作是安全的,,所以它可以被執(zhí)行很多次而不會對數據有任何影響,,也就是說執(zhí)行它一次跟執(zhí)行十次是一樣的效果。從冪等性方面來看,,多次請求跟單個請求總能得到相同的結果,。 POST一般用來在服務器端創(chuàng)建某種狀態(tài)。這個操作不具備冪等性跟安全性,,所以多次請求會在服務器端創(chuàng)建多個資源,。因為POST是不冪等的, 所以不應該被用來做跟金錢有關系的操作,,試想一次失敗的請求如果被執(zhí)行多次,,那么很可能轉賬或者支付也被執(zhí)行了多次。 PUT雖然它也可以被用來創(chuàng)建狀態(tài),,但主要還是用來在服務器端更新狀態(tài)的,。它是冪等的,但不安全,,因為它會改變服務端的狀態(tài),。因為它的冪等性,PUT可以被用來處理跟金錢有關系的操作,。 DELETE用來在服務器端刪除狀態(tài),。它也是冪等非安全的,因為它會移除服務端的狀態(tài),。它之所以是冪等的,,是因為重復刪除一個狀態(tài)的結果是一樣,。 響應狀態(tài)碼HTTP在請求資源的響應里提供了元數據信息,也就是狀態(tài)碼,。它們是web平臺之所以能用來構建分布式系統的重要因素,。它們被分為以下幾類:
頭部信息HTTP在消息頭部里為請求響應提供了額外信息。每個頭部由大小寫敏感的關鍵字和值組成,,中間用冒號隔開,。頭部信息被分為以下幾類:
資源資源可以是由系統暴露出來的任何具有唯一標識的東西。資源在應用領域跟客戶端之間建立起了聯系,。一張圖片,,一個表格,或者它們的集合,,都被看作資源,。資源通過某種呈現方式被獲取或被創(chuàng)建(XML,JSON等)。 我們與之打交道的是資源的呈現形式,,并不是資源本身,,這個跟值傳遞有點像。根據之前對REST的定義,,資源代表了在網絡上傳輸的文檔,。服務器端關心資源的狀態(tài),因為它們代表了領域的狀態(tài),。而客戶端只是獲取或者發(fā)送資源的呈現狀態(tài),,從而讓應用的狀態(tài)發(fā)生變化??蛻舳岁P心的是應用的狀態(tài),,因為這些狀態(tài)的變化跟應用所要達成的目標有關。 資源的名字都應該是具有名詞性質的,,它們代表的是系統中領域的概念,,并用URI標識。 URIs (Uniform Resource Identifiers)URIs用來唯一標識資源,。要訪問或者操作一個資源,,最起碼要知道資源的地址。它們由協議+服務器地址+路徑組成,。 客戶端不應該與資源的URI有太多耦合,,因為服務端可能隨意改變它們的值,。在這一點上,超媒體更具優(yōu)勢,。它提供了一種解耦客戶端跟URI的方式,,并在應用協議中加入新的語義。 超媒體超媒體通過超媒體控件(比如鏈接跟表單)或者URI告訴客戶端接下來可以做什么,。針對特定應用的超媒體格式是在應用的Media Type里定義的,。 超鏈接由href屬性和rel屬性組成,href指定要訪問資源的URI,,rel定義了資源跟URI的關系,。超媒體通過它們向應用的狀態(tài)轉移增加新的語義。服務端通過在響應中增加新的超鏈接來擴展新的功能,,而不會對客戶端造成影響,。只要服務端在響應里一直保留之前的鏈接,客戶端可以像之前那樣工作,,只是在要訪問新資源的時候才需要更新,。超媒體的另一個優(yōu)勢是它引入了可發(fā)現性,它提供了一種可以暴露資源的方式,,而且它是一種自文檔的協議。 客戶端通過一個固定的URL跟app開始了交互,,服務端在每一個響應里提供了后續(xù)操作的超鏈接,,這些鏈接具有良好的媒體格式,客戶端沿著這些鏈接可以做相應的操作,。 超媒體跟鏈接定義了服務器跟客戶端之間的契約,。客戶端通過鏈接與系統進行交互,,這就是HATEOAS(超媒體作為應用狀態(tài)的引擎)所表達的意思,。 Richardson成熟度模型這個模型幫助我更好地理解REST,以及如何去解釋web應用的屬性,。它把REST系統的組件分為三個等級,,并提供了一種方式去理解RESTful相關的想法,概念和優(yōu)勢,。它更像是一種理論教育模型,,而不是一種評審機制。 關于Richardson成熟度模型更具體的解釋可以看這里,。 |
|
來自: River_LaLaLa > 《RESTful》