定義
REST是“呈現狀態轉移(REpresentational State Transfer)”的縮寫。或許可以這樣來定義它:一種API的架構風格,在客戶端和服務端之間透過呈現狀態的轉移來驅動應用狀態的演進。
約束
要讓應用RESTful化,需要遵循以下約束。遵循了這些約束的分散式系統,就會擁有如下非功能屬性:效能,伸縮性,易用性,擴充套件性,可見性,可移植性和可靠性。
CS模式
CS模式透過分離客戶端和伺服器端的關注點,讓客戶端不再關注資料的儲存問題,從而提高客戶端程式碼的可移植性。另一方面,伺服器端不再關注使用者介面和使用者狀態,從而變得更簡單,提高了伸縮性。伺服器端跟客戶端可以獨立開發,只要它們都遵守契約。
無狀態
客戶端上下文在多個請求之間是絕不會儲存在伺服器上的。每個請求必須包含必要的資訊。無狀態的伺服器透過快速釋放資源和簡化實現提高了可伸縮性。可靠性使得從區域性失敗中恢復變得容易。很明顯,監控系統不必透過考慮單個請求來判斷請求的性質。 無狀態伺服器的一個缺點是降低了網路效能,因為所有需要的資料必須在每次請求中傳送。
可快取
REST應用程式是web系統,因此客戶端和中間層可以快取響應。響應必須被定義為可快取或不可快取的,以防客戶端重複使用舊資料導致降低可靠性。如果快取中的陳舊資料與已生成的請求的資料顯著不同,則由伺服器處理請求。快取可以消除一些客戶端和伺服器之間的互動,這就提升了可伸縮性、效率和透過減少平均延遲達到的使用者可感知的效能。
統一的介面
使用統一的介面降低了系統複雜度和耦合度,讓系統的不同部分可以獨立演化。稍後會解釋URI,資源和超媒體是如何透過生成標準介面來提升使用者互動可見性,降低系統複雜度,促進系統元件獨立演化的。但是我們需要在效率方面做出妥協,畢竟訊息是透過標準格式傳輸的,並不能滿足所有應用對訊息格式的要求。
分層的系統
分層系統透過約束元件的行為來降低系統複雜度,元件不能越過它們的媒介層去訪問其它層。透過元件的阻斷來保持層間的獨立性。遺留的元件可以被封裝成新的層,不讓舊的客戶端訪問。媒介層可以透過負載均衡來提升伸縮性。分層系統存在的主要不足,是它給資料處理增加了一些額外的開銷,增加了延遲,對使用者體驗有所影響。
按需編碼
REST允許客戶端透過下載執行指令碼來擴充套件它們的功能,簡化了客戶端,也提升了擴充套件性。但這同時也降低了可見性,所以這個約束不是必須遵循的。
元素
REST提供了以下幾種元素來構建無狀態,可伸縮的web API。
HTTP協議
資源
URI
超媒體
HTTP - 文字傳輸協議
REST一般使用HTTP作為它的傳輸協議,因為HTTP提供了一些很好用的特性,如HTTP動詞,狀態碼和頭部資訊
HTTP動詞
HTTP並沒有定義很多動詞來描述web服務中可能出現的行為,它只用了一個標準動詞集合來處理各種相似情況,從而讓API變得更直觀。每個動詞透過兩種屬性的組合來滿足不同的場景需求。
冪等性:操作可以被重複執行,就算在失敗以後。
安全性:對客戶端來說操作不會產生副作用。
GET
用來從伺服器端讀取狀態。這個操作是安全的,所以它可以被執行很多次而不會對資料有任何影響,也就是說執行它一次跟執行十次是一樣的效果。從冪等性方面來看,多次請求跟單個請求總能得到相同的結果。
POST
一般用來在伺服器端建立某種狀態。這個操作不具備冪等性跟安全性,所以多次請求會在伺服器端建立多個資源。因為POST是不冪等的, 所以不應該被用來做跟金錢有關係的操作,試想一次失敗的請求如果被執行多次,那麼很可能轉賬或者支付也被執行了多次。
PUT
雖然它也可以被用來建立狀態,但主要還是用來在伺服器端更新狀態的。它是冪等的,但不安全,因為它會改變服務端的狀態。因為它的冪等性,PUT可以被用來處理跟金錢有關係的操作。
DELETE
用來在伺服器端刪除狀態。它也是冪等非安全的,因為它會移除服務端的狀態。它之所以是冪等的,是因為重複刪除一個狀態的結果是一樣。
響應狀態碼
HTTP在請求資源的響應裡提供了後設資料資訊,也就是狀態碼。它們是web平臺之所以能用來構建分散式系統的重要因素。它們被分為以下幾類:
HTTP在訊息頭部裡為請求響應提供了額外資訊。每個頭部由大小寫敏感的關鍵字和值組成,中間用冒號隔開。頭部資訊被分為以下幾類:
一般頭部:在請求跟響應裡都有,跟訊息體裡傳輸的資料沒有關係。
請求頭部:更多的是關於被請求資源或者客戶端的資訊。
響應頭部:響應的額外資訊。
實體頭部:訊息體的額外資訊,比如content-length或MIMI-type。
資源
資源可以是由系統暴露出來的任何具有唯一標識的東西。資源在應用領域跟客戶端之間建立起了聯絡。一張圖片,一個表格,或者它們的集合,都被看作資源。資源透過某種呈現方式被獲取或被建立(XML,JSON等)。 我們與之打交道的是資源的呈現形式,並不是資源本身,這個跟值傳遞有點像。根據之前對REST的定義,資源代表了在網路上傳輸的文件。伺服器端關心資源的狀態,因為它們代表了領域的狀態。而客戶端只是獲取或者傳送資源的呈現狀態,從而讓應用的狀態發生變化。客戶單關心的是應用的狀態,因為這些狀態的變化跟應用所要達成的目標有關係。 資源的名字都應該是名詞性質的,它們代表的是系統中領域的概念,並用URI標識。
URIs (Uniform Resource Identifiers)
URIs用來唯一標識資源。要訪問或者操作一個資源,最起碼要知道資源的地址。它們由協議+伺服器地址+路徑組成。
客戶端不應該與資源的URI有太多耦合,因為服務端可能隨意改變它們的值。在這一點上,超媒體更具優勢。它提供了一種解耦客戶端跟URI的方式,並在應用協議中加入新的語義。
超媒體
超媒體透過超媒體控制元件(比如連結跟表單)或者URI告訴客戶端接下來可以做什麼。針對特定應用的超媒體格式是在應用的Media Type裡定義的。 超連結由href屬性和rel屬性組成,href指定要訪問資源的URI,rel定義了資源跟URI的關係。超媒體透過它們嚮應用的狀態轉移增加新的語義。服務端透過在響應中增加新的超連結來擴充套件新的功能,而不會對客戶端造成影響。只要服務端在響應裡一直保留之前的連結,客戶端可以像之前那樣工作,只是在要訪問新資源的時候才需要更新。超媒體的另一個優勢是它引入了可發現性,它提供了一種可以暴露資源的方式,而且它是一種自文件的協議。
客戶端透過一個固定的URL跟app開始了互動,服務端在每一個響應裡提供了後續操作的超連結,這些連結具有良好的媒體格式,客戶端沿著這些連結可以做相應的操作。 超媒體跟連結定義了伺服器跟客戶端之間的契約。客戶端透過連結與系統進行互動,這就是HATEOAS(超媒體作為應用狀態的引擎)所表達的意思。
Richardson 成熟度模型
這個模型幫助我更好地理解REST,以及如何去解釋web應用的屬性。它把REST系統的元件分為三個等級,並提供了一種方式去理解RESTful相關的想法,概念和優勢。它更像是一種理論教育模型,而不是一種評審機制。
PS
感謝關注「GitHub 熱門」公眾號,帶你瞭解技術圈內熱門新鮮事!
本作品採用《CC 協議》,轉載必須註明作者和本文連結