人話REST

應用之間的通信可使用Web Services,也可使用REST(表述性狀態轉移),後者由於輕量級和優雅而頗受歡迎,REST基於Http,實際上就是一套對HTTP/URI的最佳實踐套路。在設計應用時能堅持REST原則,那就預示着你將會獲得一個使用了優質架構的系統。git

使用REST,套路分解爲五條原則:github

  1. 爲資源定義IDjson

  2. 充分使用ID來作連接瀏覽器

  3. 使用標準動詞緩存

  4. 資源能夠有多重表達形式安全

  5. 無狀態服務器

定義ID

從需求文本中提取名詞和動詞是一條設計的捷徑。好比在電子商務應用中的一段需求描述:「客戶能夠點擊列表內的訂單,查詢得到此訂單」。那麼訂單(order)就是一個名詞。定義ID也就是讓每一個訂單能夠有一個ID來標識它。使用REST,標識的方式是這樣的:架構

http://example.com/order/1
http://example.com/order/2

分別代表查詢1號訂單、2號訂單。相似的,對於客戶、商品,能夠如此表達:app

http://example.com/customer/1234
http://example.com/product/4554

哦我去,那不是等於這玩意嗎:curl

class OrderManager{
     Order get(id:integer);
 }

OrderManager.get(1)

並且前面還多了一個方案(http://)和主機(example.com) ,好囉嗦。然而,好處就體如今這個囉嗦裏面了:

  1. 利用已被定義,現成的方案,易於理解的規則。

  2. 在全球範圍中一直在運行的。你的訂單能夠來自example.com,或者其餘叫作foo.com,bar.com之類的鏡像站上,它們可能分佈到全球各地。

  3. 利用現有的工具。好比訂單的連接能夠被多種渠道分享到朋友那裏,或者加入到瀏覽器的書籤中

處理單數名詞外,還有複數的,就是一組資源,相似這樣的:

http://example.com/orders/2007/11
http://example.com/products?color=green

對一類事物集合的標識。

充分利用連接表達資源和動做

連接是咱們在HTML中常見的概念,但還能夠更加通用。以下XML片斷把對應order的product和customer連接進來:

<order self="http://example.com/customers/1234"> 
   <amount>23</amount> 
   <product ref="http://example.com/products/4554"> 
       <customer ref="http://example.com/customers/1234"> </customer> 
    </product>
</order>

應用程序能夠由此XML「跟隨」連接檢索product和customer的更多數據。

還能夠經過連接加入對資源的動做。好比你的帳戶還有100美圓的狀況下,你能夠作存款取款轉帳四個操做:

GET /account/12345 HTTP/1.1

HTTP/1.1 200 OK
<?xml version="1.0"?>
<account>
    <account_number>12345</account_number>
    <balance currency="usd">100.00</balance>
    <link rel="deposit" href="/account/12345/deposit" />
    <link rel="withdraw" href="/account/12345/withdraw" />
    <link rel="transfer" href="/account/12345/transfer" />
</account>

要是你的帳戶已經赤字,你能夠作的動做就只有存款了:

GET /account/12345 HTTP/1.1

HTTP/1.1 200 OK
<?xml version="1.0"?>
<account>
    <account_number>12345</account_number>
    <balance currency="usd">-25.00</balance>
    <link rel="deposit" href="/account/12345/deposit" />
</account>

這個動做清單是和狀態有關的,術語叫作HATEOAS (Hypertext As The Engine Of Application State) 。

使用標準方法

咱們已經提過,」從需求文本中提取名詞和動詞」,名詞說了,就是資源的命名。動詞呢。好比對訂單的「查詢」就是動詞。

http://example.com/order/1

在REST內默認就是GET,也就是「查詢」。使用瀏覽器的場合,上面的URI在發給服務器時,會被翻譯爲

GET http://example.com/order/1

語義上來講,就是查詢在example.com上的ID爲1的訂單,使用http協議。當使用這套,在服務器放準守REST的話,你還能夠獲得額外的好處,就是:

冪等。若是你發送了一個GET請求沒有獲得結果,你可能不知道緣由是請求未能到達目的地,仍是響應在反饋的途中丟失了。冪等性保證了你能夠簡單地再發送一次請求解決問題。
緩存。因此在不少狀況下,你甚至不須要向服務器發送請求。

GET在HTTP中被叫作動詞(verb),除了GET,還有POST以外,還有PUT、DELETE、HEAD和OPTIONS。做爲OO開發者的話,就能夠想象到RESTful HTTP方案中的全部資源都繼承自相似於這樣的一個類:

class Resource {
     Resource(URI u);
     Response get();
     Response post(Request r);
     Response put(Request r);
     Response delete();
}

冪等性一樣適用於:

  1. PUT。語義爲:更新資源數據,若是資源不存在的話,則根據此URI建立一個新的資源

  2. DELETE。語義爲:刪除一個資源,或者刪除不存在的東西沒有任何問題

POST方法,一般表示「建立一個新資源」,也能被用於調用任意過程,於是它既不安全也不具備冪等性。

爲何使用標準方法如此重要?從根本上說,它使你的應用成爲Web的一部分,統一接口也使得全部理解HTTP應用協議的組件能與你的應用交互。通用客戶程序(generic client)就是從中受益的組件的例子,例如curl、wget、代理、緩存、HTTP服務器、網關還有Google、Yahoo!、MSN等等。

無狀態通訊

REST要求狀態要麼被放入資源狀態中,要麼保存在客戶端上。或者換句話說,服務器端不能保持除了單次請求以外的,任何與其通訊的客戶端的通訊狀態。

這樣作的最直接的理由就是可伸縮性—— 若是服務器須要保持客戶端狀態,那麼大量的客戶端交互會嚴重影響服務器的內存可用空間(footprint)。

資源多重表述

一樣一個order資源,可能響應檢索的格式是xml,爲了輕量級的支持移動app,如今須要支持json。這樣的資源表達方式變化能夠直接利用HTTP內容協商(content negotiation),而無需本身定義參數。好比原本的請求包:

GET /order/1 HTTP/1.1
Host: example.com 
Accept: application/vnd.mycompany.order+xml

如今可讓移動客戶端發出:

GET /order/1 HTTP/1.1
Host: example.com 
Accept: application/vnd.mycompany.order+json

返回的響應包內,能夠在其HTTP Content-type頭中包含着數據類型。

纔有已有標準的好處是客戶端和服務器均可以更好的達到互換:
若是客戶程序對HTTP應用協議和一組數據格式都有所「瞭解」,那麼它就能夠用一種有意義的方式與世界上任意一個RESTful HTTP應用交互。
假若從客戶端傳來的數據符合應用協議,那麼服務器端就可使用特定的格式處理數據,而不去關心客戶端的類型

原文: https://www.infoq.com/article...
改編自: http://www.infoq.com/cn/artic...

demo code : https://github.com/1000copy/s...

相關文章
相關標籤/搜索