天天看點

REST是什麼?RESTFul又是什麼?這二者的關系是怎樣的?

REST是什麼?RESTFul又是什麼?這二者的關系是怎樣的?

RESTFul 和 RPC 的差別是什麼?

REST(一種軟體架構風格)

全稱:Representational State Transfer

含義:(表述性 狀态 轉移)

是一種針對網絡應用的設計和開發方式,可以降低開發的複雜性,提高系統的可伸縮性。

在目前主流的三種Web服務互動方案中,REST相比于SOAP(Simple Object Access protocol,簡單對象通路協定)以及XML-RPC更加簡單明了,無論是對URL的處理還是對Payload的編碼,REST都傾向于用更加簡單、輕量的方法設計和實作。值得注意的是REST并沒有一個明确的标準,而更像是一種設計的風格。

原則條件

REST 指的是一組架構限制條件和原則,如果你在設計應用程式時能堅持REST原則,那就預示着你将會得到一個使用了優質Web架構的系統。Web 應用程式最重要的 REST 原則是:

  • 用戶端和伺服器之間的互動在請求之間是無狀态的。
  • 從用戶端到伺服器的每個請求都必須包含了解請求所必需的資訊。
  • 如果伺服器在請求之間的任何時間點重新開機,用戶端不會得到通知。
  • 無狀态請求可以由任何可用伺服器回答,這十分适合雲計算之類的環境。
  • 用戶端可以緩存資料以改進性能。
  • 在伺服器端,應用程式狀态和功能可以分為各種資源。資源是一個概念實體,它向用戶端公開。資源的例子有:應用程式對象、資料庫記錄、算法等等。每個資源都使用 URI (Universal Resource Identifier) 得到一個唯一的位址。所有資源都共享統一的接口,以便在用戶端和伺服器之間傳輸狀态。
  • 使用的是标準的 HTTP 方法,比如 GET、PUT、POST 和 DELETE。Hypermedia 是應用程式狀态的引擎,資源表示通過超連結互聯。

注意:

REST除了給我們帶來了一個嶄新的架構以外,還有一個重要的貢獻是在開發系統過程中的一種新的思維方式:通過url來設計系統的結構。根據REST,每個url都代表一個resource,而整個系統就是由這些resource組成的。是以,如果url是設計良好的,那麼系統的結構就也應該是設計良好的。

RESTful:(REST式的)

基于REST這種軟體架構風格設計的 API接口 即稱為:RESTful API

即設計的這些接口滿足 RESTful 接口設計規範

接口設計規範的具體内容為:

1. 域名

應該盡量将API部署在專用域名之下。

https://api.example.com
           

如果确定API很簡單,不會有進一步擴充,可以考慮放在主域名下。

https://example.org/api/
           
2. 版本(Versioning)

應該将API的版本号放入URL。

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

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

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

另一種做法是,将版本号放在HTTP頭資訊中,但不如放入URL友善和直覺。Github就采用了這種做法。

因為不同的版本,可以了解成同一種資源的不同表現形式,是以應該采用同一個URL。版本号可以在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
           
3. 路徑(Endpoint)

路徑又稱"終點"(endpoint),表示API的具體網址,每個網址代表一種資源(resource)

(1) 資源作為網址,隻能有名詞,不能有動詞,而且所用的名詞往往與資料庫的表名對應。

舉例來說,以下是不好的例子:

/getProducts
/listOrders
/retreiveClientByOrder?orderId=1
           

對于一個簡潔結構,你應該始終用名詞。 此外,利用的HTTP方法可以分離網址中的資源名稱的操作。

GET /products :将傳回所有産品清單
POST /products :将産品建立到集合
GET /products/4 :将擷取産品 4
PATCH(或)PUT /products/4 :将更新産品 4
           

(2) API中的名詞應該使用複數。無論子資源或者所有資源。

舉例來說,擷取産品的API可以這樣定義

擷取單個産品:http://127.0.0.1:8080/AppName/rest/products/1
擷取所有産品: http://127.0.0.1:8080/AppName/rest/products
           
4. HTTP動詞

對于資源的具體操作類型,由HTTP動詞表示。

常用的HTTP動詞有下面四個(括号裡是對應的SQL指令)。

  • GET(SELECT):從伺服器取出資源(一項或多項)。
  • POST(CREATE):在伺服器建立一個資源。
  • PUT(UPDATE):在伺服器更新資源(用戶端提供改變後的完整資源)。
  • DELETE(DELETE):從伺服器删除資源。

還有三個不常用的HTTP動詞。

  • PATCH(UPDATE):在伺服器更新(更新)資源(用戶端提供改變的屬性)。
  • HEAD:擷取資源的中繼資料。
  • OPTIONS:擷取資訊,關于資源的哪些屬性是用戶端可以改變的。

下面是一些例子。

GET /zoos:列出所有動物園
POST /zoos:建立一個動物園(上傳檔案)
GET /zoos/ID:擷取某個指定動物園的資訊
PUT /zoos/ID:更新某個指定動物園的資訊(提供該動物園的全部資訊)
PATCH /zoos/ID:更新某個指定動物園的資訊(提供該動物園的部分資訊)
DELETE /zoos/ID:删除某個動物園
GET /zoos/ID/animals:列出某個指定動物園的所有動物
DELETE /zoos/ID/animals/ID:删除某個指定動物園的指定動物
           
5. 過濾資訊(Filtering)

如果記錄數量很多,伺服器不可能都将它們傳回給使用者。API應該提供參數,過濾傳回結果。

下面是一些常見的參數。query_string 查詢字元串,位址欄後面問号後面的資料,格式: name=xx&sss=xxx

?limit=10:指定傳回記錄的數量
?offset=10:指定傳回記錄的開始位置。
?page=2&per_page=100:指定第幾頁,以及每頁的記錄數。
?sortby=name&order=asc:指定傳回結果按照哪個屬性排序,以及排序順序。
?animal_type_id=1:指定篩選條件
           

參數的設計允許存在備援,即允許API路徑和URL參數偶爾有重複。比如,GET /zoos/ID/animals 與 GET /animals?zoo_id=ID 的含義是相同的。

6. 狀态碼(Status Codes)

伺服器向使用者傳回的狀态碼和提示資訊,常見的有以下一些(方括号中是該狀态碼對應的HTTP動詞)。

  • 200 OK - [GET]:伺服器成功傳回使用者請求的資料
  • 201 CREATED - [POST/PUT/PATCH]:使用者建立或修改資料成功。
  • 202 Accepted - [*]:表示一個請求已經進入背景排隊(異步任務)
  • 204 NO CONTENT - [DELETE]:使用者删除資料成功。
  • 400 INVALID REQUEST - [POST/PUT/PATCH]:使用者發出的請求有錯誤,伺服器沒有進行建立或修改資料的操作
  • 401 Unauthorized - [*]:表示使用者沒有權限(令牌、使用者名、密碼錯誤)。
  • 403 Forbidden - [*] 表示使用者得到授權(與401錯誤相對),但是通路是被禁止的。
  • 404 NOT FOUND - [*]:使用者發出的請求針對的是不存在的記錄,伺服器沒有進行操作,該操作是幂等的。
  • 406 Not Acceptable - [GET]:使用者請求的格式不可得(比如使用者請求JSON格式,但是隻有XML格式)。
  • 410 Gone -[GET]:使用者請求的資源被永久删除,且不會再得到的。
  • 422 Unprocesable entity - [POST/PUT/PATCH] 當建立一個對象時,發生一個驗證錯誤。
  • 500 INTERNAL SERVER ERROR - [*]:伺服器發生錯誤,使用者将無法判斷發出的請求是否成功。

狀态碼的完全清單參見這裡或這裡。

7. 錯誤處理(Error handling)

如果狀态碼是4xx,伺服器就應該向使用者傳回出錯資訊。一般來說,傳回的資訊中将error作為鍵名,出錯資訊作為鍵值即可。

{
    error: "Invalid API key"
}
           
8. 傳回結果

針對不同操作,伺服器向使用者傳回的結果應該符合以下規範。

  • GET /collection:傳回資源對象的清單(數組)
  • GET /collection/ID:傳回單個資源對象(json)
  • POST /collection:傳回新生成的資源對象(json)
  • PUT /collection/ID:傳回完整的資源對象(json)
  • DELETE /collection/ID:傳回一個空文檔(空字元串)
9. 超媒體(Hypermedia API)

RESTful API最好做到Hypermedia(即傳回結果中提供連結,連向其他API方法),使得使用者不查文檔,也知道下一步應該做什麼。

比如,Github的API就是這種設計,通路api.github.com會得到一個所有可用API的網址清單。

{
"current_user_url": "https://api.github.com/user",
"authorizations_url": "https://api.github.com/authorizations",
// ...
}
           

從上面可以看到,如果想擷取目前使用者的資訊,應該去通路api.github.com/user,然後就得到了下面結果。

{
  "message": "Requires authentication",
  "documentation_url": "https://developer.github.com/v3"
}
           

上面代碼表示,伺服器給出了提示資訊,以及文檔的網址。

10. 其他

伺服器傳回的資料格式,應該盡量使用JSON,避免使用XML。

RESTful架構

RESTful架構是對MVC架構改進後所形成的一種架構,通過使用事先定義好的接口與不同的服務聯系起來。在RESTful架構中,浏覽器使用POST,DELETE,PUT和GET四種請求方式分别對指定的URL資源進行增删改查操作。是以,RESTful是通過URI實作對資源的管理及通路,具有擴充性強、結構清晰的特點。
RESTful架構将伺服器分成前端伺服器和後端伺服器兩部分,前端伺服器為使用者提供無模型的視圖;後端伺服器為前端伺服器提供接口。浏覽器向前端伺服器請求視圖,通過視圖中包含的AJAX函數發起接口請求擷取模型。
項目開發引入RESTful架構,利于團隊并行開發。在RESTful架構中,将多數HTTP請求轉移到前端伺服器上,降低伺服器的負荷,使視圖擷取後端模型失敗也能呈現。但RESTful架構卻不适用于所有的項目,當項目比較小時無需使用RESTful架構,項目變得更加複雜。

RESTful與 RPC

使用 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,還可能包括 HEAD 和 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 和 Delicious API 都使用這種混合架構。

RPC

RPC是遠端過程調用(Remote Procedure Call)的縮寫形式。

SAP系統RPC調用的原理其實很簡單,有一些類似于三層構架的C/S系統,第三方的客戶程式通過接口調用SAP内部的标準或自定義函數,獲得函數傳回的資料進行處理後顯示或列印。

原理圖示:

REST是什麼?RESTFul又是什麼?這二者的關系是怎樣的?

應用場景:

RPC在分布式系統中的系統環境建設和應用程式設計中有着廣泛的應用,應用包括如下方面:

1、分布式作業系統的程序間通訊

程序間通訊是作業系統必須提供的基本設施之一,分布式作業系統必須提供分布于異構的結點機上程序間的通訊機制,RPC是實作消息傳送模式的分布式程序間通訊的手段之一。

2、構造分布式計算的軟體環境

由于分布式軟體環境本身地理上的分布性, 它的各個組成成份之間存在大量的互動和通訊,R P C 是其基本的實作方法之一。ONC+和DCE兩個流行的分式布計算軟體環境都是使用RPC構造的,其它一些分布式軟體環境也采用了RPC方式。

3、遠端資料庫服務

在分布式資料庫系統中,資料庫一般駐存在伺服器上,客戶機通過遠端資料庫服務功能通路資料庫伺服器,現有的遠端資料庫服務是使用RPC模式的。例如,Sybase和Oracle都提供了存儲過程機制,系統與使用者定義的存儲過程存儲在資料庫伺服器上,使用者在用戶端使用RPC模式調用存儲過程。

4、分布式應用程式設計

RPC機制與RPC工具為分布式應用程式設計提供了手段和友善, 使用者可以無需知道網絡結構和協定細節而直接使用RPC工具設計分布式應用程式。

5、分布式程式的調試

RPC可用于分布式程式的調試。使用反向RPC使伺服器成為客戶并向它的客戶程序發出RPC,可以調試分布式程式。例如,在伺服器上運作一個遠端調試程式,它不斷接收用戶端的RPC,當遇到一個調試程式斷點時,它向客戶機發回一個RPC,通知斷點已經到達,這也是RPC用于程序通訊的例子。

IPC:程序間通信

程序間通信(IPC)是在多任務作業系統或聯網的計算機之間運作的程式和程序所用的通信技術。有兩種類型的程序間通信(IPC)。

LPC:本地過程調用

本地過程調用(LPC)用在多任務作業系統中,使得同時運作的任務能互相會話。這些任務共享記憶體空間使任務同步和互相發送資訊。

抟扶搖而上者九萬裡