[Controller] - RESTful架構 與 REST原則

前言

RESTful架構,就是目前最流行的一種互聯網軟件架構。它結構清晰、符合標準、易於理解、擴展方便,因此正獲得愈來愈多網站的採用。html

可是,到底什麼是RESTful架構,什麼是REST原則,二者是什麼關係?前端

一句話總結:REST 指的是一組"架構"的約束條件和原則。知足這些約束條件和原則的應用程序或設計就是 RESTful。web

即,若是一個架構符合REST原則,就稱它爲RESTful架構。
算法

基礎概念:數據庫

REST是設計風格而不是標準。
REST一般基於使用HTTP,URI,和XML以及HTML這些現有的普遍流行的協議和標準。

資源是一個概念實體,它向客戶端公開。

資源是由URI來指定。
對資源的操做(獲取、建立、修改和刪除資源),正好對應HTTP協議提供的GET、POST、PUT和DELETE方法。

經過操做資源的表現形式來操做資源。
資源的表現形式則是XML或者HTML,取決於讀者是機器仍是人,是消費web服務的客戶軟件仍是web瀏覽器。固然也能夠是任何其餘的格式。

什麼是REST?

REST (Representation State Transfer) 描述了一個架構樣式的網絡系統,好比 web 應用程序。REST 一詞的出於 2000 nian Roy Fielding (HTTP1.0/1.1 規範的主要編寫者之一)的博士論文《Architectural Styles and the Design of Network-based Software Architectures》中,簡單的從標題來看,它應該是一種架構樣式 (Architectural Styles) 與軟件架構 (Software Architectures),並且是以網絡 (Network-based) 爲基礎,重點就是:json

  • 架構樣式 (Architectural Styles)設計模式

  • 軟件架構 (Software Architectures)api

  • 網絡 (Network-based) 爲基礎瀏覽器

REST 指的是一組架構約束條件和原則,是設計風格而不是標準知足這些約束條件和原則的應用程序或設計就是 RESTful。緩存

REST 談論的是: 如何正確地使用 Web標準,例如,HTTP 和 URI。因此,想要了解 REST 就是要先瞭解 Web 及其工做方式。若是你設計的應用程序能符合 REST 原則 (REST principles),這些符合 REST 原則的 REST 服務可稱爲 "RESTful web service" 也稱 "RESTful Web API"。"-ful" 字尾強調它們的設計徹底符合 REST 論文裏的建議內容。

資源(Resources)

REST的名稱"表現層狀態轉化"中,省略了主語。"表現層"其實指的是"資源"(Resources)的"表現層"。

 REST 中的資源 (Resource) 表明整個網絡上的資源(一個概念實體,或者說是一個具體信息)。

在服務器端,應用程序狀態和功能能夠分爲各類資源。資源是一個有趣的概念實體,它向客戶端公開。

網絡上提供了各式各樣的資源(資源的例子有:應用程序對象、數據庫記錄、算法一段文本、一張圖片、一首歌曲、一種服務等等),而每一個資源都使用 URI (統一資源標識符,Uniform Resource Identifier) 獲得一個唯一的地址。你能夠用一個URI(統一資源定位符)指向它,每種資源對應一個特定的URI。要獲取這個資源,訪問它的URI就能夠,所以URI就成了每個資源的地址或獨一無二的識別符。

所謂"上網",就是與互聯網上一系列的"資源"互動,調用它的URI。

表現層(Representation)

全部資源都共享在統一的層面上,以便在客戶端和服務器之間傳輸狀態。

"資源"是一種信息概念實體,它能夠有多種外在表現形式。咱們把"資源"具體呈現出來的形式,叫作它的"表現層"(Representation)。

注意:網絡上是經過操做資源的表現形式來操做資源的。

好比,文本能夠用txt格式表現,也能夠用HTML格式、XML格式、JSON格式表現,甚至能夠採用二進制格式;圖片能夠用JPG格式表現,也能夠用PNG格式表現。

URI只表明資源的實體,不表明它的形式。嚴格地說,有些網址最後的".html"後綴名是沒必要要的,由於這個後綴名錶示格式,屬於"表現層"範疇,而URI應該只表明"資源"的位置。它的具體表現形式,應該在HTTP請求的頭信息中用Accept和Content-Type字段指定,這兩個字段纔是對"表現層"的描述。

狀態轉化(State Transfer)

訪問一個網站,就表明了客戶端和服務器的一個互動過程。在這個過程當中,勢必涉及到數據和狀態的變化。

互聯網通訊協議HTTP協議,是一個無狀態協議。這意味着,客戶端和服務器之間的交互在請求之間是無狀態的,全部的狀態都保存在服務器端。所以,若是客戶端想要操做服務器,必須經過某種手段,讓服務器端發生"狀態轉化"(State Transfer)。而全部資源都共享在統一的表現層上(以便在客戶端和服務器之間傳輸狀態),這種轉化是創建在表現層之上的,因此就是"表現層狀態轉化"。

若是服務器在請求之間的任什麼時候間點重啓,客戶端不會獲得通知。此外,無狀態請求能夠由任何可用服務器回答,這十分適合雲計算之類的環境。客戶端能夠緩存數據以改進性能。

客戶端用到的手段,只能是HTTP協議。具體來講,在 HTTP/1.1 RFC 2616第 5.1.1 Method 一節定義了八大類 HTTP 方法,除了咱們經常使用的 GET 與 POST 以外,在 REST 中經常使用的還有 PUT 與 DELETE。此 GET, POST, PUT, DELETE 正好能夠對應咱們 CRUD (Create, Read, Update, Delete) 四種數據操做。

HTTP Method 與 CURD 數據處理操做對應

HTTP方法

數據處理 說明
POST Create 新增一個沒有id的資源

GET

Read 取得一個資源
PUT Update 更新一個資源。或新增一個含 id 資源(若是 id 不存在)
DELETE Delete 刪除一個資源

綜述

綜合上面的解釋,咱們總結一下什麼是RESTful架構:

  (1)每個URI表明一種資源;

  (2)客戶端和服務器之間,傳遞這種資源的某種表現層;

  (3)客戶端經過四個HTTP動詞,對服務器端資源進行操做,實現"表現層狀態轉化"。


REST 簡化了客戶端和服務器的實現

另外一個重要的 REST 原則是分層系統,這表示組件沒法瞭解它與之交互的中間層之外的組件。經過將系統知識限制在單個層,能夠限制整個系統的複雜性,促進了底層的獨立性。

當 REST 架構的約束條件做爲一個總體應用時,將生成一個能夠擴展到大量客戶端的應用程序。它還下降了客戶端和服務器之間的交互延遲。統一界面簡化了整個系統架構,改進了子系統之間交互的可見性。


REST的優勢 

  1. 能夠利用緩存Cache來提升響應速度 

  2. 通信自己的無狀態性可讓不一樣的服務器的處理一系列請求中的不一樣請求,提升服務器的擴展性 

  3. 瀏覽器便可做爲客戶端,簡化軟件需求 

  4. 相對於其餘疊加在HTTP協議之上的機制,REST的軟件依賴性更小 

  5. 不須要額外的資源發現機制 

  6. 在軟件技術演進中的長期的兼容性更好


什麼是REST:結束語

REST 描述了一個架構樣式的互聯繫統(如 Web 應用程序)。REST 約束條件做爲一個總體應用時,將生成一個簡單、可擴展、有效、安全、可靠的架構。因爲它簡便、輕量級以及經過 HTTP 直接傳輸數據的特性,RESTful Web 服務成爲基於 SOAP 服務的一個最有前途的替代方an。用於 web 服務和動態 Web 應用程序的多層架構能夠實現可重用性、簡單性、可擴展性和組件可響應性的清晰分離。Ajax 和 RESTful Web 服務本質上是互爲補充的。開發人員能夠輕鬆使用 Ajax 和 RESTful Web 服務一塊兒建立豐富的界面。

RESTful API 設計指南

參考

RESTful API 設計指南 做者: 阮一峯

六步實現Rest風格的API


RESTful的實現 - (來源於網絡)

RESTful Web 服務與 RPC 樣式的 Web 服務

瞭解了什麼是REST,咱們再看看RESTful的實現。最近,使用 RPC 樣式架構構建的基於 SOAP 的 Web 服務成爲實現 SOA 最經常使用的方法。RPC 樣式的 Web 服務客戶端將一個裝滿數據的信封(包括方法和參數信息)經過 HTTP 發送到服務器。服務器打開信封並使用傳入參數執行指定的方法。方法的結果打包到一個信封並做爲響應發回客戶端。客戶端收到響應並打開信封。每一個對象都有本身獨特的方法以及僅公開一個 URI 的 RPC 樣式 Web 服務,URI 表示單個端點。它忽略 HTTP 的大部分特性且僅支持 POST 方法。

因爲輕量級以及經過 HTTP 直接傳輸數據的特性,Web 服務的 RESTful 方法已經成爲最多見的替代方法。可使用各類語言(好比 Java 程序、Perl、Ruby、Python、PHP 和 Javascript[包括 Ajax])實現客戶端。RESTful Web 服務一般能夠經過自動客戶端或表明用戶的應用程序訪問。可是,這種服務的簡便性讓用戶可以與之直接交互,使用它們的 Web 瀏覽器構建一個 GET URL 並讀取返回的內容。

在 REST 樣式的 Web 服務中,每一個資源都有一個地址。資源自己都是方法調用的目標,方法列表對全部資源都是同樣的。這些方法都是標準方法,包括 HTTP GET、POST、PUT、DELETE,還可能包括 HEADER 和 OPTIONS。

在 RPC 樣式的架構中,關注點在於方法,而在 REST 樣式的架構中,關注點在於資源 —— 將使用標準方法檢索並操做信息片斷(使用表示的形式)。資源表示形式在表示形式中使用超連接互聯。

Leonard Richardson 和 Sam Ruby 在他們的著做 RESTful Web Services 中引入了術語 REST-RPC 混合架構。REST-RPC 混合 Web 服務不使用信封包裝方法、參數和數據,而是直接經過 HTTP 傳輸數據,這與 REST 樣式的 Web 服務是相似的。可是它不使用標準的 HTTP 方法操做資源。它在 HTTP 請求的 URI 部分存儲方法信息。好幾個知名的 Web 服務,好比 Yahoo 的 Flickr API 和 del.icio.us API 都使用這種混合架構。

RESTful Web 服務的 Java 框架

有兩個 Java 框架能夠幫助構建 RESTful Web 服務。erome Louvel 和 Dave Pawson 開發的 Restlet(見 參考資料)是輕量級的。它實現針對各類 RESTful 系統的資源、表示、鏈接器和媒體類型之類的概念,包括 Web 服務。在 Restlet 框架中,客戶端和服務器都是組件。組件經過鏈接器互相通訊。該框架最重要的類是抽象類 Uniform 及其具體的子類 Restlet,該類的子類是zhuan用類,好比 Application、Filter、Finder、Router 和 Route。這些子類可以一塊兒處理驗證、過濾、安全、數據轉換以及將傳入請求路由到相應資源等操做。Resource 類生成客戶端的表示形式。

JSR-311是 Sun Microsystems 的規範,能夠爲開發 RESTful Web 服務定義一組 Java API。Jersey是對 JSR-311 的參考實現。

JSR-311 提供一組註釋,相關類和接口均可以用來將 Java 對象做爲 Web 資源展現。該規範假定 HTTP 是底層網絡協議。它使用註釋提供 URI 和相應資源類之間的清晰映射,以及 HTTP 方法與 Java 對象方法之間的映射。API 支持普遍的 HTTP 實體內容類型,包括 HTML、XML、JSON、GIF、JPG 等。它還將提供所需的插件功能,以容許使用標準方法經過應用程序添加其餘類型。

構建 RESTful Web 服務的多層架構

RESTful Web 服務和動態 Web 應用程序在許多方面都是相似的。有時它們提供相同或很是相似的數據和函數,儘管客戶端的種類不一樣。例如,在線電子商務分類網站爲用戶提供一個瀏覽器界面,用於搜索、查看和訂購產品。若是還提供 Web 服務供公司、零售商甚至我的可以自動訂購產品,它將很是有用。與大部分動態 Web 應用程序同樣,Web 服務能夠從多層架構的關注點分離中受益。業務邏輯和數據能夠由自動客戶端和 GUI 客戶端共享。唯一的不一樣點在於客戶端的本質和中間層的表示層。此外,從數據訪問中分離業務邏輯可實現數據庫獨立性,併爲各類類型的數據存儲提供插件能力。

圖 1 展現了自動化客戶端,包括 Java 和各類語言編寫的腳本,這些語言包括 Python、Perl、Ruby、PHP 或命令行工具,好比 curl。在瀏覽器中運行且做爲 RESTful Web 服務消費者運行的 Ajax、Flash、JavaFX、GWT、博客和 wiki 都屬於此列,由於它們都表明用戶以自動化樣式運行。自動化 Web 服務客戶端在 Web 層向 Resource Request Handler 發送 HTTP 響應。客戶端的無狀態請求在頭部包含方法信息,即 POST、GET、PUT 和 DELETE,這又將映射到 Resource Request Handler 中資源的相應操做。每一個請求都包含全部必需的信息,包括 Resource Request Handler 用來處理請求的憑據。

從 Web 服務客戶端收到請求以後,Resource Request Handler 從業務邏輯層請求服務。Resource Request Handler 肯定全部概念性的實體,系統將這些實體做爲資源公開,併爲每一個資源分配一個唯一的 URI。可是,概念性的實體在該層是不存在的。它們存在於業務邏輯層。可使用 Jersey 或其餘框架(好比 Restlet)實現 Resource Request Handler,它應該是輕量級的,將大量職責工做委託給業務層。

Ajax 和 RESTful Web 服務本質上是互爲補充的。它們均可以利用大量 Web 技術和標準,好比 HTML、JavaScript、瀏覽器對象、XML/JSON 和 HTTP。固然也不須要購買、安裝或配置任何主要組件來支持 Ajax 前端和 RESTful Web 服務之間的交互。RESTful Web 服務爲 Ajax 提供了很是簡單的 API 來處理服務器上資源之間的交互。

圖 1 中的 Web 瀏覽器客戶端做爲 GUI 的前端,使用表示層中的 Browser Request Handler 生成的 HTML 提供顯示功能。Browser Requester Handler 可使用 MVC 模型(JSF、Struts 或 Spring 都是 Java 的例子)。它從瀏覽器接受請求,從業務邏輯層請求服務,生成表示並對瀏覽器作出響應。表示供用戶在瀏覽器中顯示使用。表示不只包含內容,還包含顯示的屬性,好比 HTML 和 CSS。

多層 Web 應用程序環境圖 

業務規則能夠集中到業務邏輯層,該層充當表示層和數據訪問層之間的數據交換的中間層。數據以域對象或值對象的形式提供給表示層。從業務邏輯層中解耦 Browser Request Handler 和 Resource Request Handler 有助於促進代碼重用,並能實現靈活和可擴展的架構。此外,因爲未來可使用新的 REST 和 MVC 框架,實現它們變得更加容易,無需重寫業務邏輯層。

數據訪問層提供與數據存儲層的交互,可使用 DAO 設計模式或者對象-關係映射解決方an(如 Hibernate、OJB 或 iBATIS)實現。做爲替代方an,業務層和數據訪問層中的組件能夠實現爲 EJB 組件,並取得 EJB 容器的支持,該容器能夠爲組件生命週期提供便利,管理持久性、事務和資源配置。可是,這須要一個聽從 Java EE 的應用服務器(好比 JBoss),而且可能沒法處理 Tomcat。該層的做用在於針對不一樣的數據存儲技術,從業務邏輯中分離數據訪問代碼。數據訪問層還能夠做爲鏈接其餘系統的集成點,能夠成爲其餘 Web 服務的客戶端。

數據存儲層包括數據庫系統、LDAP 服務器、文件系統和企業信息系統(包括遺留系統、事務處理系統和企業資源規劃系統)。使用該架構,您能夠開始看到 RESTful Web 服務的力量,它能夠靈活地成爲任何企業數據存儲的統一 API,從而向以用戶爲中心的 Web 應用程序公開垂直數據,並自動化批量報告腳本。

RESTful架構設計誤區

RESTful架構有一些典型的設計誤區。

最多見的一種設計錯誤,就是URI包含動詞。由於"資源"表示一種實體,因此應該是名詞,URI不該該有動詞,動詞應該放在HTTP協議中。

舉例來講,某個URI是/posts/show/1,其中show是動詞,這個URI就設計錯了,正確的寫法應該是/posts/1,而後用GET方法表示show。

若是某些動做是HTTP動詞表示不了的,你就應該把動做作成一種資源。好比網上匯款,從帳戶1向帳戶2匯款500元,錯誤的URI是:

  POST /accounts/1/transfer/500/to/2

正確的寫法是把動詞transfer改爲名詞transaction,資源不能是動詞,可是能夠是一種服務:

  POST /transaction HTTP/1.1
  Host: 127.0.0.1
  
  from=1&to=2&amount=500.00

另外一個設計誤區,就是在URI中加入版本號:

  http://www.example.com/app/1.0/foo

  http://www.example.com/app/1.1/foo

  http://www.example.com/app/2.0/foo

由於不一樣的版本,能夠理解成同一種資源的不一樣表現形式,因此應該採用同一個URI。版本號能夠在HTTP請求頭信息的Accept字段中進行區分(參見Versioning REST Services):

  Accept: vnd.example-com.foo+json; version=1.0

  Accept: vnd.example-com.foo+json; version=1.1

  Accept: vnd.example-com.foo+json; version=2.0

總結

REST的要求

客戶端和服務器結構 

鏈接協議具備無狀態性 

可以利用Cache機制增進性能 

層次化的系統 

隨需代碼 - Javascript (可選) 


RESTful Web 服務

RESTful Web 服務(也稱爲 RESTful Web API)是一個使用HTTP並遵循REST原則的Web服務。

PUT 和 DELETE 方法是冪等方法。GET方法是安全方法 (不會對服務器端有修改,所以也是冪等的)。

不像基於SOAP的Web服務,RESTful Web服務並無的「正式」標準。 這是由於REST是一種架構,而SOAP只是一個協議。雖然REST不是一個標準,但在實現RESTful Web服務時可使用其餘各類標準(好比HTTP,URL,XML,PNG等)。

(完)

參考資料

理解RESTful架構 做者: 阮一峯

【推薦】

  1. Spring3.0將全面支持REST

  2. 對於REST中無狀態(stateless)的一點認識

  3. 基於JavaScript的REST客戶端框架

  4. RIA+REST架構實現完美WEB開發

  5. REST構架風格介紹:狀態表述轉移

相關文章
相關標籤/搜索