Rest風格WEB服務(Rest Style Web Service)的真相

寫這篇文章是目的不是介紹Web-Service, 而是從Restful Web Service提及來剖析一下 前端

什麼才是真正的Restful Style的架構與協議,從而更好的理解web服務的設計理念與架 程序員

構本質。 web

一:Web Service基礎知識 編程

一個最簡單web服務就一個web頁面等待請求與處理。更容易理解的方式是Web  瀏覽器

Service能夠把一個應用變成一個基本WEB方式的請求與處理的應用。常見的兩種 緩存

Web Service處理方式爲: ruby

a.      基於WSDL/SOAP的方式 服務器

b.      Rest方式 網絡

方式a是比較正統的,客戶端調用必須先取得WSDL文件,而後生成調用的API纔可 架構

以使用。它不是我要說的重點,基本調用流程以下:


方式b是Rest方式,Rest的Web Service的設計原則是基於CRUD,其支持四種操做分

別爲:

GET – 獲取信息/請求信息內容,絕大多數瀏覽器獲取信息時使用該方式。

POST – 增長信息內容,顯示之前的信息內容,能夠看做是insert操做

PUT – 更新信息內容,至關與update

DELETE – 刪除信息內容能夠看做是delete

 

Rest方式更加簡單便捷,若是從設計原則上看HTTP協議自己已是最Restful風格的

協議了HTTP協議很好的支持了CRUD的操做。正是由於如此,WEB2.0以來, 基於

Restful的Web Service愈來愈多的成爲首選。

 

二:認識RestfulStyle

Rest的全稱是可表述狀態遷移(RepresentationalState Transfer), 可能從字面看有點奇怪

HTTP協議自己無狀態協議,其保持鏈接經過設置請求頭字段Connection: keep-alive

設置過時時間來同時控制。其實Rest方式的WebService也是無狀態的這樣作的好處最少

有如下兩個:

1.      更好的負載平衡,減輕服務器端負擔

2.      更快的客戶端響應,減小沒必要要的狀態檢查。

 

Restful 風格的興起,要感謝互聯網巨頭Google,Facebook等他們提供大量基於Restful

風格的web服務,從谷歌地圖到天氣預報到翻譯,國內的互聯網巨頭騰訊,新浪微博也

發佈自己的web服務,吸引更多的開發者加入他們的陣營。Rest除了知足基本的CRUD

設計原則之外,還要遵循以下約定:

1.      資源操做能夠經過描述來實現即Representation

2.      消息自己是無狀態與自我描述(傳輸支持XML與JSON)

3.      能夠發送與接受多個Representation

 

Rest風格(Restful Style)架構原則:

1.      客戶服務器方式

2.      無狀態協議傳輸

3.      支持緩存

4.      統一接口定義

5.      分層系統設計

這樣發佈了Rest的Web服務API其改變不會影響到客戶端程序與實現。若是你的系統

不能適用Rest風格的架構怎麼辦,從新設計一個新的架構,擴展Rest風格架構。可是

這個世界上絕大數的系統與應用要作的事情就是CRUD。

 

三. Rest與HTTP

上面已經提到過HTTP協議多是最Rest風格的協議,而HTTP1.1協議設計的一個原則

就要實現Rest風格。因此毫無疑問HTTP的GET, POST, PUT, DELETE就是最好的證實

可是Rest風格是否能夠應用到其它一些協議與系統設計中嘛,答案是確定的,一個最好

的例子證實就POP3協議, POP3支持Fetch 數據記錄,查詢記錄,更新記錄與刪除記錄

(記錄表明email)多麼完美的Rest風格協議。


已經存在的HTTP協議應用:

1.      瀏覽器客戶端(你每天上網,不是IE就是Chrome,或者其它瀏覽器,你懂的)

2.      即時消息通訊,MSN/Skype支持

3.      各類內容管理系統

4.      博客系統與微博客戶端應用。

5.      你能夠來補充/?

 

Rest消息詳解:

1.      跟咱們如今知道的HTTP URI沒有什麼分別,Google靜態地圖就是一個很好的例子

         只是URL加上不一樣參數就能夠fetch不一樣的地圖內容。

2.      能夠支持任何類型的數據傳輸,這點與基於XML與JSON的信息傳輸有點同,後者

         更希望傳輸文本內容與結構化文本內容

3.      SOAP與XML-RPC有嚴格的消息格式限制,rest沒有消息格式要求。客戶端調用方

         便啊!

 

Rest風格Web服務的好處,顯然易見一個好處就是簡化了客戶端的調用,再也不像WSDL

般麻煩。從而減低第三方開發者的學習成本,減短了學習曲線。有利於服務推廣與普

及,吸引更多用戶數量從而帶來潛在的商業利益。

 

在軟件即服務(SaaS - Software As A Service)與軟件即平臺(PasS-Platform 

As A Service)中有着重要的地位與應用。這正是那些互聯網巨頭對Rest風

格感興趣的緣由之一。

 

四:Rest風格架構

Rest風格能夠用在非WEB的系統設計與架構中嘛/?打答案是確定的,Rest能夠用在任何

統設計中,從本質是上Rest不是一種技術,而是一種架構原則,固然能夠用來架構非

WEB的系統。系統越大風格越要象Rest方式如此纔是一個成功的架構。

 

WEB中的面向對象編程

ExtJS, KendoUI(基於JQuery)等JavaScript庫已經支持很是方便的從URL中fetch內容

新數據,前端設計愈來愈趨向於更加細化的分層設計,而不只僅是MVC。客戶端

程序員應該更多的專一前臺用戶體驗,因爲這些框架良好的封裝與可擴展行,

JavaScript等語言編程越來越多的引入面向對象的概念與實踐。能夠好不誇張的說如

今的JavaScript編程與十年以前已經有本質不一樣。

原博客地址

==============================================

網上的說法:

  • REST是一種針對網絡應用的設計和開發方式,能夠下降開發的複雜性,提升系統的可伸縮性。REST提出了一些設計概念和準則:
    1. 網絡上的全部事物都被抽象爲資源(resource);
    2. 每一個資源對應一個惟一的資源標識(resource identifier);
    3. 經過通用的鏈接器接口(generic connector interface)對資源進行操做;
    4. 對資源的各類操做不會改變資源標識;
    5. 全部的操做都是無狀態的(stateless)。
這陣子正打算用Rails作個東東,因此開始系統地學習起了Rails。巧合的是,大概兩週前,dlee邀請我加入Fielding博士關於REST的那篇論文的翻譯團隊。能夠說Rails和REST這兩個最熱門的詞彙幾乎同時擠入了個人生活。隨着我對Rails的學習和對[Fielding]的翻譯,我也開始對REST產生了一些不太成熟的想法,寫在這裏與你們分享,同時也起到拋磚引玉的做用,歡迎你們討論。

先複習一下REST的基本思想。[Fielding]把REST形式化地定義爲一種架構風格(architecture style),它有架構元素(element)和架構約束(constraint)組成。這些概念比較晦澀難懂,並且咱們作工程的每每並不須要形而上的理解。咱們只知道,REST是一種針對網絡應用的設計和開發方式,能夠下降開發的複雜性,提升系統的可伸縮性。REST提出了一些設計概念和準則:
  1. 網絡上的全部事物都被抽象爲資源(resource);
  2. 每一個資源對應一個惟一的資源標識(resource identifier);
  3. 經過通用的鏈接器接口(generic connector interface)對資源進行操做;
  4. 對資源的各類操做不會改變資源標識;
  5. 全部的操做都是無狀態的(stateless)。
對於當今最多見的網絡應用來講,resource identifier是url,generic connector interface是HTTP,第4條準則就是咱們常說的url不變性。這些概念中的resouce最容易令人產生誤解。resouce所指的並非數據,而是數據+特定的表現形式(representation),這也是爲何REST的全名是Representational State Transfer的緣由。舉個例子來講,「本月賣得最好的10本書」和「你最喜歡的10本書」在數據上可能有重疊(有一本書即賣得好,你又喜歡),甚至徹底相同。可是它們的representation不一樣,所以是不一樣的resource。

REST之因此可以簡化開發,是由於其引入的架構約束,好比Rails 1.2中對REST的實現默認把controller中的方法限制在7個:index、show、new、edit、create、update和destory,這實際上就是對CURD的實現。更進一步講,Rails(也是當今大部分網絡應用)使用HTTP做爲generic connector interface,HTTP則把對一個url的操做限制在了4個以內:GET、POST、PUT和DELETE。

REST之因此可以提升系統的可伸縮性,是由於它強制全部操做都是stateless的,這樣就沒有context的約束,若是要作分佈式、作集羣,就不須要考慮context的問題了。同時,它令系統能夠有效地使用pool。REST對性能的另外一個提高來自其對client和server任務的分配:server只負責提供resource以及操做resource的服務,而client要根據resource中的data和representation本身作render。這就減小了服務器的開銷。

既然REST有這樣的好處,那咱們應該義無反顧地擁抱它啊!目前一些大牛(像DHH)都已經開始投入到了REST的世界,那咱們這些人應該作什麼或者說思考寫什麼你呢?我以爲咱們應該思考兩個問題:
  1. 如何使用REST;
  2. REST和MVC的關係。
第一個問題假設REST是咱們應該採用的架構,而後討論如何使用;第二個問題則要說明REST和當前最廣泛應用的MVC是什麼關係,互補仍是取代?

咱們先來談談第一個問題,如何使用REST。我感受,REST除了給咱們帶來了一個嶄新的架構之外,還有一個重要的貢獻是在開發系統過程當中的一種新的思惟方式:經過url來設計系統的結構。根據REST,每一個url都表明一個resource,而整個系統就是由這些resource組成的。所以,若是url是設計良好的,那麼系統的結構就也應該是設計良好的。對於非高手級的開發人員來講,考慮一個系統如何架構老是一個很抽象的問題。敏捷開發所提倡的Test Driven Development,其好處之一(我以爲是最大的好處)就是能夠經過testcase直觀地設計系統的接口。好比在尚未建立一個class的時候就編寫一個testcase,雖然設置不能經過編譯,可是testcase中的方法調用能夠很好地從class使用者的角度反映出須要的接口,從而爲class的設計提供了直觀的表現。這與在REST架構中經過url設計系統結構很是相似。雖然咱們連一個功能都沒有實現,可是咱們能夠先設計出咱們認爲合理的url,這些url甚至不能鏈接到任何page或action,可是它們直觀地告訴咱們:系統對用戶的訪問接口就應該是這樣。根據這些url,咱們能夠很方便地設計系統的結構。

讓我在這裏重申一遍:REST容許咱們經過url設計系統,就像Test Driven Development容許咱們使用testcase設計class接口同樣。

OK,既然url有這樣的好處,那咱們就着重討論一下如何設計url。網絡應用一般都是有hierarchy的,像棵大樹。咱們一般但願url也能反映出資源的層次性。好比對於一個blog應用:/articles表示全部的文章,/articles/1表示id爲1的文章,這都比較直觀。遺憾的是,網絡應用的資源結構永遠不會如此簡單。所以人們經常會問這樣一個問題:RESTful的url能覆蓋全部的用戶請求嗎?好比,login如何RESTful?search如何RESTful?

從REST的概念上來看,全部能夠被抽象爲資源的東東均可以使用RESTful的url。所以對於上面的兩個問題,若是login和search能夠被抽象爲資源,那麼就可使用RESTful的url。search比較簡單,由於它會返回搜索結果,所以能夠被抽象爲資源,而且只實現index方法就能夠了(只須要顯示搜索結果,沒有create、destory之類的東西)。然而這裏面也有一個問題:search的關鍵字如何傳給server?index方法顯然應該使用HTTP GET,這會把關鍵字加到url後面,固然不符合REST的風格。要解決這個問題,能夠把每次search看做一個資源,所以要建立create和index方法,create用來在用戶點擊「搜索」按鈕是經過HTTP POST把關鍵字傳給server,而後index則用來顯示搜索結果。這樣一來,咱們還能夠記錄用戶的搜索歷史。使用一樣的方法,咱們也能夠對login應用REST,即每次login動做是一個資源。

如今,咱們來複雜一些的東東。如何用url表達「category爲ruby的article」?一開始可能想到的是/category/ruby/articles,這種想法很直觀。可是我以爲裏面的category是不須要的,咱們能夠直接把「/ruby」理解爲「category是ruby」,也就是說「ruby」出現的位置說明了它指的就是category。OK,/ruby/articles,單單從這個url上看,咱們能得到多少關於category的信息呢?顯然category隱藏在了url後面,這樣作到底好很差,應該是仁者見仁,智者見智了。對於如何表達category這樣的東西,我還沒想出很好的方式,你們有什麼好idea,能夠一塊兒討論。

另外還有一種url形式,它對應到程序中的繼承關係。好比product是一個父類,book和computer是其子類。那麼全部產品的url應該是/products,全部書籍的url應該是/books,全部電腦的url應該是/computers。這一想法就比較直觀了,並且再次驗證了url能夠幫助咱們進行設計的論點。

讓我再說明一下個人想法:若是每一個用戶需求均可以抽象爲資源,那麼就能夠徹底使用REST。

由此看來,使用REST的關鍵是如何抽象資源,抽象得越精確,對REST的應用就越好。所以,如何改變咱們目前根深蒂固的基於action的思想是最重要的。

有了對第一個問題的討論,第二個問題就容易討論多了。REST會取代MVC嗎?仍是彼此是互補關係(就像AOP對於OOP)?答案是It depends!若是咱們能夠把全部的用戶需求均可以抽象爲資源,那麼MVC就能夠推出歷史的舞臺了。若是狀況相反,那麼咱們就須要混合使用REST和MVC。

固然,這是很是理想的論斷。可能咱們沒法找到一種方法能夠把全部的用戶需求都抽象爲資源,由於保證這種抽象的完整性(即真的是全部需求均可以)須要形式化的證實。並且即便被證實出來了,因爲開發人員的能力和喜愛不一樣,MVC確定也會成爲很多人的首選。可是對於但願擁抱REST的人來講,這些都沒有關係。只要你開發的系統所設計的問題域能夠被合理地抽象爲資源,那麼REST就會成爲你的開發利器。

原文
相關文章
相關標籤/搜索