淺談REST
REST架構風格是全新的針對Web應用的開發風格,是當今世界最成功的網際網路超媒體分散式系統架構,它使得人們真正理解了HTTP協議本來面貌。隨著REST架構成為主流技術,一種全新的網際網路網路應用開發的思維方式開始流行。
一、REST是什麼
REST是英文Representational State Transfer的縮寫,中文翻譯為“表述性狀態轉移”,它是由Roy Thomas Fielding博士在他的論文 《Architectural Styles and the Design of Network-based Software Architectures》中提出的一個術語。REST本身只是為分散式超媒體系統設計的一種架構風格,而不是標準。
基於Web的架構,實際上就是各種規範的集合,這些規範共同組成了Web架構。比如HTTP協議、比如客戶端伺服器模式,這些都是規範。每當我們在原有規範的基礎上增加新的規範,就會形成新的架構。而REST正是這樣一種架構,它結合了一系列的規範,而形成了一種新的基於Web的架構風格。
傳統的Web應用大都是B/S架構,它包括瞭如下一些規範。
1.客戶-伺服器:這種規範的提出,改善了使用者介面跨多個平臺的可移植性,並且通過簡化伺服器元件,改善了系統的可伸縮性。最為關鍵的是通過分離使用者介面和資料儲存這兩個關注點,使得不同使用者終端享受相同資料成為了可能。
2.無狀態性:無狀態性是在客戶-伺服器約束的基礎上新增的又一層規範。它要求通訊必須在本質上是無狀態的,即從客戶到伺服器的每個request都必須包含理解該request所必須的所有資訊。這個規範改善了系統的可見性(無狀態性使得客戶端和伺服器端不必儲存對方的詳細資訊,伺服器只需要處理當前request,而不必瞭解所有的request歷史),可靠性(無狀態性減少了伺服器從區域性錯誤中恢復的任務量),可伸縮性(無狀態性使得伺服器端可以很容易的釋放資源,因為伺服器端不必在多個request中儲存狀態)。同時,這種規範的缺點也是顯而易見得,由於不能將狀態資料儲存在伺服器上的共享上下文中,因此增加了在一系列request中傳送重複資料的開銷,嚴重的降低了效率。
3.快取:為了改善無狀態性帶來的網路的低效性,我們新增了快取約束。快取約束允許隱式或顯式地標記一個response中的資料,這樣就賦予了客戶端快取response資料的功能,這樣就可以為以後的request共用快取的資料,部分或全部的消除一部分互動,增加了網路的效率。但是用於客戶端快取了資訊,也就同時增加了客戶端與伺服器資料不一致的可能,從而降低了可靠性。
B/S架構的優點是其部署非常方便,但在使用者體驗方面卻不是很理想。為了改善這種情況,我們引入了REST!
REST在原有的架構上增加了三個新規範:統一介面、分層系統和按需程式碼。
1.統一介面:REST架構風格的核心特徵就是強調元件之間有一個統一的介面,這表現在REST世界裡,網路上所有的事物都被抽象為資源,而REST就是通過通用的連結器介面對資源進行操作。這樣設計的好處是保證系統提供的服務都是解耦的,極大的簡化了系統,從而改善了系統的互動性和可重用性;並且REST針對Web的常見情況做了優化,使得REST介面被設計為可以高效的轉移大粒度的超媒體資料,這也就導致了REST介面對其它的架構並不是最優的。
2.分層系統:分層系統規則的加入提高了各種層次之間的獨立性,為整個系統的複雜性設定了邊界,通過封裝遺留的服務,使新的伺服器免受遺留客戶端的影響,這也就提高了系統的可伸縮性。
3.按需程式碼:REST允許對客戶端功能進行擴充套件。比如,通過下載並執行applet或指令碼形式的程式碼,來擴充套件客戶端功能。但這在改善系統可擴充套件性的同時,也降低了可見性。所以它只是REST的一個可選的約束。
二、REST的設計準則
REST架構是針對Web應用而設計的,其目的是為了降低開發的複雜性,提高系統的可伸縮性。REST提出瞭如下設計準則:
1.網路上的所有事物都被抽象為資源(resource);
2.每個資源對應一個唯一的資源識別符號(resource identifier);
3.通過通用的聯結器介面(generic connector interface)對資源進行操作;
4.對資源的各種操作不會改變資源識別符號;
5.所有的操作都是無狀態的(stateless)。
REST中的資源所指的不是資料,而是資料和表現形式的組合,比如“最新訪問的10位會員”和“最活躍的10位會員”在資料上可能有重疊或者完全相同,而由於它們的表現形式不同,所以被歸為不同的資源,這也就是為什麼REST的全名是Representational State Transfer的原因。資源識別符號就是URI(Uniform Resource Identifier),不管是圖片,Word還是視訊檔案,甚至只是一種虛擬的服務,也不管你是xml格式,txt檔案格式還是其它檔案格式,全部通過URI對資源進行唯一的標識。
REST是基於HTTP協議的,任何對資源的操作行為都是通過HTTP協議來實現。以往的Web開發大多數用的都是HTTP協議中的GET和POST方法,對其他方法很少使用,這實際上是因為對HTTP協議認識片面的理解造成的。HTTP不僅僅是一個簡單的運載資料的協議,而是一個具有豐富內涵的網路軟體的協議。它不僅僅能對網際網路資源進行唯一定位,而且還能告訴我們如何對該資源進行操作。HTTP把對一個資源的操作限制在4個方法以內:GET,POST,PUT和DELETE,這正是對資源CRUD操作的實現。由於資源和URI是一一對應的,執行這些操作的時候URI是沒有變化的,這和以往的Web開發有很大的區別。正由於這一點,極大的簡化了Web開發,也使得URI可以被設計成更為直觀的反映資源的結構,這種URI的設計被稱作RESTful的URI,這為開發人員引入了一種新的思維方式:通過URL來設計系統結構。當然,這種設計方式對一些特定情況也是不適用的,也就是說不是所有的URI都可以RESTful的。
REST之所以可以提高系統的可伸縮性,就是因為它要求所有的操作都是無狀態的。由於沒有了上下文(Context)的約束,做分散式和叢集的時候就更為簡單,也可以讓系統更為有效的利用緩衝池(Pool),並且由於伺服器端不需要記錄客戶端的一系列訪問,也減輕了伺服器端的效能開銷。
三、使用REST架構
對於開發人員來說,關心的是如何使用REST架構,這裡我們來簡單談談這個問題。
REST不僅僅是一種嶄新的架構,它帶來的更是一種全新的Web開發過程中的思維方式:通過URL來設計系統結構。在REST中,所有的URL都對應著資源,只要URL的設計是良好的,那麼其呈現的系統結構也就是良好的。這點和TDD(Test Driven Development)很相似,它是通過測試用例來設計系統的介面,每一個測試用例都表示一系列使用者的需求。開發人員不需要一開始就編寫功能,而只需要把需要實現的功能通過測試用例的形式表現出來即可。這個和REST中通過URL設計系統結構的方式類似,我們只需要根據需求設計出合理地URL,這些URL不一定非要連結到指定的頁面或者完成一些行為,只要它們能夠直觀的表現出系統的使用者介面。根據這些URL,我們就可以方便的設計系統結構。從REST架構的概念上來看,所有能夠被抽象成資源的東西都可以被指定為一個URL,而開發人員所需要做的工作就是如何能把使用者需求抽象為資源,以及如何抽象的精確。因為對資源抽象的越為精確,對REST的應用來說就越好,這個和傳統MVC開發模式中基於Action的思想差別就非常大。設計良好的URL,不但對於開發人員來說可以更明確的認識系統結構,對使用者來說也方便記憶和識別資源,因為URL足夠簡單和有意義。按照以往的設計模式,很多URL後面都是一堆引數,對於使用者來說也是很不方便的。
既然REST這麼好用,那麼是不是所有的Web應用都能採取此種架構呢?答案是否定的。我們知道,直到現在為止,MVC(Model-View-Controller)模式依然是Web開發最普遍的模式,絕大多數的公司和開發人員都採取此種架構來開發Web應用,並且其思維方式也停留於此。MVC模式由資料,檢視和控制器構成,通過事件(Event)觸發Controller來改變Model和View。加上Webwork,Struts等開源框架的加入,MVC開發模式已經相當成熟,其思想根本就是基於Action來驅動。從開發人員角度上來說,貿然接受一個新的架構會帶來風險,其中的不確定因素太多,並且REST新的思維方式是把所有使用者需求抽象為資源,這在實際開發中是比較難做到的,因為並不是所有的使用者需求都能被抽象為資源,這樣也就是說不是整個系統的結構都能通過REST的來表現。所以在開發中,我們需要根據以上2點來在REST和MVC中做出選擇。我們認為比較好的辦法是混用REST和MVC,因為這適合絕大多數的Web應用開發,開發人員只需要對比較容易能夠抽象為資源的使用者需求採取REST的開發模式,而對其它需求採取MVC開發即可。這裡需要提到的就是ROR(Ruby on Rails)框架,這是一個基於Ruby語言的越來越流行的Web開發框架,它極大的提高了Web開發的速度。更為重要的是,ROR(從1.2版本起)框架是第一個引入REST做為核心思想的Web開發框架,它提供了對REST最好的支援,也是當今最成功的應用REST的Web開發框架。實際上,ROR的REST實現就是REST和MVC混用,開發人員採用ROR框架,可以更快更好的構建Web應用。
對開發人員來說,REST不僅僅在Web開發上貢獻了自己的力量,同時也讓我們學到了如何把軟體工程原則系統地應用於對一個真實軟體的設計和評估上。
相關文章
- 淺淺談ReduxRedux
- 淺淺淺談JavaScript作用域JavaScript
- 淺談 PromisePromise
- 淺談mockMock
- 淺談ViewModelView
- 淺談PWA
- 淺談Disruptor
- 淺談反射反射
- 淺談vuexVue
- ElasticSearch淺談Elasticsearch
- 淺談NginxNginx
- 淺談promisePromise
- 淺談visibility
- 淺談flutterFlutter
- 淺談JMM
- Celery淺談
- 淺談JavaScriptJavaScript
- 淺談IHttpHandlerHTTP
- 淺談HTTPSHTTP
- 淺談SYNPROXY
- 淺談WebSocketWeb
- 淺談HTMLHTML
- ZooKeeper淺談
- ElasticJob淺談AST
- 淺談RMQMQ
- 淺談ThinkPHP 5.0PHP
- 淺談event loopOOP
- iOS 淺談 RunloopiOSOOP
- 淺談 Trait 類AI
- React淺談setStateReact
- 淺談React HooksReactHook
- 淺談Spring框架Spring框架
- 淺談TCP/IPTCP
- 淺談promise用法Promise
- 淺談品牌管理
- 淺談Mysql索引MySql索引
- 淺談async/awaitAI
- 淺談redux(一)Redux
- 淺談Spring BeanSpringBean