濟南軟件開(kāi)發(fā)—爲什麼(me)REST如此重要

2015-10-13 14:44:31
    本文濟南軟件開(kāi)發(fā)將(jiāng)讨論 REST,它定義了一組體系架構原則,您可以根據這(zhè)些原則設計以系統資源爲中心的 Web 服務,這(zhè)是一個非常容易讓人誤解的概念。本文主要是寫給那些想設計 WebService API 但卻對(duì) REST 沒(méi)有十分清晰認識的開(kāi)發(fā)者們。在本文最後(hòu)會(huì)附上一些資源供大家學(xué)習,這(zhè)些資源講解非常詳細。
  什麼(me)是REST?
  表征狀态轉移(Representional State Transfer),是 Roy Fielding( HTTP 規範的主要編寫者之一)博士在 2000 年他的博士論文中提出來的一種(zhǒng)軟件架構風格。它并不是一個标準,而是通過(guò)表征(Representional )來描述傳輸狀态的一種(zhǒng)原則。其宗旨是從資源的角度來觀察整個網絡,分布在各處的資源由 URI 确定,而客戶端的應用通過(guò) URI 來獲取資源的表征。獲得這(zhè)些表征緻使這(zhè)些應用程序轉變了其狀态。随著(zhe)不斷獲取資源的表征,客戶端應用不斷地在轉變著(zhe)其狀态。
  目前在三種(zhǒng)主流的 Web 服務實現方案中,因爲 REST 模式的 Web 服務與複雜的 SOAP 和 XML-RPC 相對(duì)比,更加簡潔,越來越多的 Web 服務開(kāi)始采用 REST 風格設計和實現。例如,Amazon.com 提供接近 REST 風格的 Web 服務進(jìn)行圖書查找;雅虎提供的 Web 服務也是 REST 風格的。
  讓我們來思考一下:
  Marcus 是一個農民,他有 4 頭牛,12 隻雞和 3 頭奶牛。他現在模拟一個 REST API,而我是客戶端。如果我想用 REST 來請求當前的農場狀态,我僅會(huì)問:“State?”Marcus 會(huì)回答:“4 頭豬、12 隻雞、3 頭奶牛”。
  這(zhè)是 REST 最簡單的一個例子。Marcus 使用表征來傳輸農場狀态。表征的句子很簡單:“4 頭豬、12 隻雞、3 頭奶牛”。
  再往下看,看我如何讓 Marcus 用 REST 方式添加 2 頭奶牛?
  按照常理,可以會(huì)這(zhè)樣(yàng)說:Marcus,請在農場你再添加 2 頭奶牛。難道(dào)這(zhè)就(jiù)是 REST 方式嗎?難道(dào)就(jiù)是通過(guò)這(zhè)樣(yàng)的表征來傳輸狀态的嗎?不是的!這(zhè)是一個遠程過(guò)程調用,過(guò)程是給農場添加 2 頭奶牛。
  Marcus 很憤怒地響應到:“400,Bad Request”,你到底是什麼(me)意思?
  所以,讓我們重新來一次。我們怎樣(yàng)做到 REST 方式呢?該怎樣(yàng)重新表征呢?它應該是 4 頭豬、12 隻雞、3 頭奶牛。好(hǎo),讓我們再次重新表征……
  我:“Marcus,……4 頭豬、12 隻雞、5頭奶牛!”
  Marcus:“好(hǎo)的”。
  我:“Marcus,現在是什麼(me)狀态?”
  Marcus:“4 頭豬、12 隻雞、5 頭奶牛”。
  我:“好(hǎo)!”
  看到了嗎?就(jiù)這(zhè)樣(yàng)簡單。
  爲什麼(me) RPC 也不夠好(hǎo)?
  從邏輯角度來看,爲什麼(me)會(huì)更加青睐 REST 而不是 RPC(Remote Procedure Call,遠程過(guò)程調用 ),因爲它極大的降低了我們溝通的複雜度,通過(guò)把表征作爲唯一的溝通的方式。無需去讨論過(guò)程(添加一頭牛?增加一種(zhǒng)動物類型?給雞的數量翻倍還(hái)是賣掉所有豬?)我們隻需讨論表征,并且使用這(zhè)個表征來達到我們想要的目标,很簡單,不是嗎?我不希望和 Marcus 的溝通失敗,因爲我們彼此的理解過(guò)程會(huì)不一樣(yàng),所以隻需要知道(dào)最後(hòu)的狀态就(jiù)行。但這(zhè)僅僅是創建 RPC 會(huì)産生許多問題之一。如果你使用 RPC,你需要設計一些程序嵌入到某種(zhǒng)結構中。這(zhè)種(zhǒng)結構需要存儲參數、錯誤的代碼、返回值等。我已經(jīng)看到許多公司這(zhè)樣(yàng)做,他們設計自己的 RPC-結構來實現客戶端與服務器端的交互,但卻産生許多問題。你爲什麼(me)要這(zhè)麼(me)做?爲什麼(me)要創建自己的 RPC-結構?這(zhè)樣(yàng)做的好(hǎo)處是?倘若我想要讓應用程序使用許多 WebService,并且這(zhè)些 WebService 帶有多個 RPC-格式屬性?那麼(me)我不得不去開(kāi)發(fā)一些類似這(zhè)樣(yàng)的東西:
  如果你們真的需要 RPC,至少要選擇一個類似 SOAP 的标準。
  但 SOAP 也很糟糕
  即使 RPC 的标準真的很令人痛苦,但我不得不承認 ACID 事(shì)務,一個完整的标準化服務描述性語言 SOAP(Simple Object Access Protocol,簡單對(duì)象訪問協議)在某些環境下表現的還(hái)不錯。盡管如此,SOAP 産品的性能(néng)開(kāi)銷很大,它是一個巨大的性能(néng)殺手。雖然 REST 不是一個标準,但在實現 RESTful Web 服務時可以使用其他各種(zhǒng)标準(比如 HTTP、URL、XML、PNG 等)。
  Session 更邪惡
  你無需 Session!但有人會(huì)說:“我想要保存用戶購物車裡(lǐ)的商品,所以我必須要 Session!”不,這(zhè)樣(yàng)想是錯誤的!即使沒(méi)有 Session,你也可以做你任何你想做的事(shì)情。你可以隻需在 URL 裡(lǐ)封裝購物車信息,或者爲購物車創建另一個資源,比如“/carts/5235”。
  不需要與客戶端進(jìn)行會(huì)話,通過(guò)這(zhè)些操作(指在 URL 裡(lǐ)封裝購物車信息,或者爲購物車創建另一個資源,比如“/carts/5235”)後(hòu),客戶端向(xiàng)服務器發(fā)出請求後(hòu),哪怕你在服務器上執行卸載平台和操作系統、拆除服務器硬件、重新組裝服務器、重新安裝操作系統、平台、應用程序備份恢複操作,也不會(huì)影響客戶端。
  不要強迫客戶端保存狀态,這(zhè)樣(yàng)做不僅複雜,而且還(hái)會(huì)帶來許多問題,你應該從你的 Web 應用程序裡(lǐ)删除有狀态的東西。
  不要重造超媒體
  目前,超媒體已經(jīng)相當普及,我提醒大家,不要再去重新造輪子。這(zhè)裡(lǐ)已經(jīng)有許多,足夠你使用了:
采用原子鏈接規範的超媒體,類似 spring-hateoas 和 spring-data-rest。