天天看點

為啥REST如此重要?

本文我們将讨論 REST,它定義了一組體系架構原則,您可以根據這些原則設計以系統資源為中心的 Web 服務,這是一個非常容易讓人誤解的概念。本文主要是寫給那些想設計 WebService API 但卻對 REST 沒有十厘清晰認識的開發者們。在本文最後會附上一些資源供大家學習,這些資源講解非常詳細。

   什麼是 REST?

  表征狀态轉移(Representional State Transfer),是 Roy Fielding( HTTP 規範的主要編寫者之一)博士在 2000 年他的博士論文中提出來的一種軟體架構風格。它并不是一個标準,而是通過表征(Representional )來描述傳輸狀态的一種原則。其宗旨是從資源的角度來觀察整個網絡,分布在各處的資源由 URI 确定,而用戶端的應用通過 URI 來擷取資源的表征。獲得這些表征緻使這些應用程式轉變了其狀态。随着不斷擷取資源的表征,用戶端應用不斷地在轉變着其狀态。

  目前在三種主流的 Web 服務實作方案中,因為 REST 模式的 Web 服務與複雜的 SOAP 和 XML-RPC 相對比,更加簡潔,越來越多的 Web 服務開始采用 REST 風格設計和實作。例如,Amazon.com 提供接近 REST 風格的 Web 服務進行圖書查找;雅虎提供的 Web 服務也是 REST 風格的。

  讓我們來思考一下:

  Marcus 是一個農民,他有 4 頭牛,12 隻雞和 3 頭奶牛。他現在模拟一個 REST API,而我是用戶端。如果我想用 REST 來請求目前的農場狀态,我僅會問:“State?”Marcus 會回答:“4 頭豬、12 隻雞、3 頭奶牛”。

  這是 REST 最簡單的一個例子。Marcus 使用表征來傳輸農場狀态。表征的句子很簡單:“4 頭豬、12 隻雞、3 頭奶牛”。

  再往下看,看我如何讓 Marcus 用 REST 方式添加 2 頭奶牛?

  按照常理,可以會這樣說:Marcus,請在農場你再添加 2 頭奶牛。難道這就是 REST 方式嗎?難道就是通過這樣的表征來傳輸狀态的嗎?不是的!這是一個遠端過程調用,過程是給農場添加 2 頭奶牛。

  Marcus 很憤怒地響應到:“400,Bad Request”,你到底是什麼意思?

  是以,讓我們重新來一次。我們怎樣做到 REST 方式呢?該怎樣重新表征呢?它應該是 4 頭豬、12 隻雞、3 頭奶牛。好,讓我們再次重新表征……

  我:“Marcus,……4 頭豬、12 隻雞、 5 頭奶牛!”

  Marcus:“好的”。

  我:“Marcus,現在是什麼狀态?”

  Marcus:“4 頭豬、12 隻雞、5 頭奶牛”。

  我:“好!”

  看到了嗎?就這樣簡單。

   為什麼 RPC 也不夠好?

  從邏輯角度來看,為什麼會更加青睐 REST 而不是 RPC(Remote Procedure Call,遠端過程調用 ),因為它極大的降低了我們溝通的複雜度,通過把表征作為唯一的溝通的方式。無需去讨論過程(添加一頭牛?增加一種動物類型?給雞的數量翻倍還是賣掉所有豬?)我們隻需讨論表征,并且使用這個表征來達到我們想要的目标,很簡單,不是嗎?我不希望和 Marcus 的溝通失敗,因為我們彼此的了解過程會不一樣,是以隻需要知道最後的狀态就行。但這僅僅是建立 RPC 會産生許多問題之一。如果你使用 RPC,你需要設計一些程式嵌入到某種結構中。這種結構需要存儲參數、錯誤的代碼、傳回值等。我已經看到許多公司這樣做,他們設計自己的 RPC-結構來實作用戶端與伺服器端的互動,但卻産生許多問題。你為什麼要這麼做?為什麼要建立自己的 RPC-結構?這樣做的好處是?倘若我想要讓應用程式使用許多 WebService,并且這些 WebService 帶有多個 RPC-格式屬性?那麼我不得不去開發一些類似這樣的東西:

為啥REST如此重要?

  如果你們真的需要 RPC,至少要選擇一個類似 SOAP 的标準。

   但 SOAP 也很糟糕

  即使 RPC 的标準真的很令人痛苦,但我不得不承認 ACID 事務,一個完整的标準化服務描述性語言 SOAP(Simple Object Access Protocol,簡單對象通路協定)在某些環境下表現的還不錯。盡管如此,SOAP 産品的性能開銷很大,它是一個巨大的性能殺手。雖然 REST 不是一個标準,但在實作 RESTful Web 服務時可以使用其他各種标準(比如 HTTP、URL、XML、PNG 等)。

   Session 更邪惡

  你無需 Session!但有人會說:“我想要儲存使用者購物車裡的商品,是以我必須要 Session!”不,這樣想是錯誤的!即使沒有 Session,你也可以做你任何你想做的事情。你可以隻需在 URL 裡封裝購物車資訊,或者為購物車建立另一個資源,比如“/carts/5235”。

  不需要與用戶端進行會話,通過這些操作(指在 URL 裡封裝購物車資訊,或者為購物車建立另一個資源,比如“/carts/5235”)後,用戶端向伺服器送出請求後,哪怕你在伺服器上執行解除安裝平台和作業系統、拆除伺服器硬體、重新組裝伺服器、重新安裝作業系統、平台、應用程式備份恢複操作,也不會影響用戶端。

  不要強迫用戶端儲存狀态,這樣做不僅複雜,而且還會帶來許多問題,你應該從你的 Web 應用程式裡删除有狀态的東西。

   不要重造超媒體

  目前,超媒體已經相當普及,我提醒大家,不要再去重新造輪子。這裡已經有許多,足夠你使用了:

  • 采用 原子連結規範的超媒體,類似 spring-hateoas 和 spring-data-rest。
  • JSON-HAL
  • JSON-LD
  • ……

英文原文: Why REST is so important

譯文原文:http://ju.outofmemory.cn/entry/40376

繼續閱讀