REST - 為初學者解釋

在網路開發中,沒有任何主題比「Representational State Transfer」(具象狀態傳輸),也就是廣為人知的 REST,更讓人困惑了。這個詞來自於 第 5 章,取自 Roy Fielding加州大學爾灣分校的博士論文。

在這篇文章中,我們將瀏覽本章節,並為非學術性的網路開發人員總結重要概念。該論文內容繁雜,包含許多與對正式博士論文寫作不感興趣的學術界人士無關的技術術語。

在閱讀完這篇文章後,您應該會對 REST 以及特別是 統一介面 的概念有更好的掌握。

#概述

關於 REST,首先要了解的是,它是對原始網路的描述。Fielding 將 REST 描述為「分散式超媒體系統的架構風格」,這聽起來很花俏,但實際上指的就是我們所熟知和喜愛的網路:點擊超連結、提交表單、查看圖像、閱讀段落以及所有相關內容。

並不是被創造出來作為描述 JSON API 的特定方法,儘管大多數人今天聽到 REST 時都會想到這個背景。Fielding 當時描述的是早期的網路,特別是它與早期客戶端/伺服器架構的不同之處。

#第 5.1 節 推導 REST

第 5.1 節中,很不幸地,對非學術界人士來說,Fielding 採用了從第一原理推導 REST 的技術。在此,我將總結每個章節,並在重要的章節中澄清和添加背景。

#客戶端-伺服器

REST 當然是一種客戶端-伺服器架構,因為網路是一個客戶端(瀏覽器)伺服器(HTTP 伺服器)系統。

#無狀態

大多數開發人員都知道,網路的設計是無狀態的。所有請求都應封裝理解該請求所需的所有資訊。例如,不應存在與一系列請求隱式關聯的長期運行交易,就像您可能在 SQL 資料庫會話中擁有的那樣。

#快取

您可能知道,HTTP 內建了一個 快取機制。您現在不需要知道詳細資訊,但可以稍後再探索它。

#統一介面

在我看來,本節是 REST 架構的關鍵所在,不幸的是,它非常簡短,因此我們將花一些時間來擴展它,而不僅僅是總結它。本章的開頭是

將 REST 架構風格與其他基於網路的風格區分開來的核心特徵是它強調元件之間的統一介面

為了闡明關於統一介面到底是什麼的討論,讓我們考慮一些簡單的 HTML,我希望每個閱讀這篇文章的人都能理解

<html>
  <body>
  <section>
    <p>
      Name: Joe Blow
    </p>
    <p>
      Email: joe@blow.com
    </p>
    <p>
      <a href="/contacts/42/edit">Edit</a>
      <a href="/contacts/42/email">Email</a>
      <a href="/contacts/42/archive">Archive</a>
    </p>
  </section>
</body>
</html>

這裡我們有一些基本的 HTML,其中包含一些 div、一些資訊,然後是一些錨點標籤,用於對聯絡人執行各種操作。沒什麼特別的。同樣,在討論中,假設此內容可以在 http://example.com/contacts/42 找到。

回到論文

REST 由四個介面約束定義:資源識別;通過表示來操作資源;自我描述性訊息;以及超媒體作為應用程式狀態的引擎。

讓我們依次瀏覽這些內容。

#資源識別

REST 的第一個方面是資源的概念,這些資源可以通過... 嗯,通用資源定位器,也就是 URL 來找到。請注意,HTML 包含其他 URL,用於對此資源 (contacts/42) 執行的操作,遵循 URL 路徑的傳統層次結構排列。

#通過表示來操作資源

這聽起來很花俏,但它只是意味著您可以通過各種表示(也就是 HTML 頁面)來更新和變更資源(也就是聯絡人),而不必發出 SQL 來修改它。

#自我描述性訊息

這是 REST 的一個關鍵概念。請注意,瀏覽器(也就是這個客戶端-伺服器設置中的客戶端)對聯絡人一無所知。然而,它能夠僅通過呈現伺服器返回的 HTML 來呈現「聯絡人 UI」。訊息本身是完全自我描述的,包含客戶端所需的有關資料和該資料上可能執行的操作的所有資訊(以連結的形式)。

現在,將其與相同資料的 JSON 表示進行對比

    {
      "name" : "Joe Blow",
      "email" : "joe@example.com"
    }

顯然,它更小,但是使用此資料的客戶端必須決定兩個關鍵事項

第一部分通常使用客戶端模板完成。第二部分通常通過閱讀 API 的文件,並直接在客戶端中編碼與伺服器的互動來完成。

這是 REST 風格系統和傳統客戶端-伺服器系統之間差異的關鍵:在 REST 風格系統中,客戶端(也就是瀏覽器)對資源一無所知,它只知道如何呈現超媒體。在客戶端-伺服器系統中,有關資源的知識嵌入在客戶端中。

這兩種方法各有優缺點,但是 REST 風格方法,以早期網路的形式,被證明是非常可靠和靈活的。它將大量關於資源的知識隱藏在這個 HTML 的統一介面之後,因此客戶端沒有機會像胖客戶端那樣被破壞。

現在,您可能已經注意到,在過去的十年中,網路開發已經偏離了 REST 風格架構,而轉向了使用 JSON API 的更傳統的客戶端-伺服器設置。您可能已經注意到,關於版本化 API、提供更通用的查詢功能等等的討論和問題也更多了。這並非偶然:當我們將瀏覽器變成託管胖客戶端應用程式的 VM 時,我們正在失去 REST 風格模型的靈活性。

#超媒體作為應用程式狀態的引擎 (HATEOAS)

最後一個概念與前一個概念相符:客戶端通過與超媒體本身中找到的 URL(通過表單和連結)互動來轉換應用程式狀態。因此,在上面的 HTML 範例中,編輯、發送電子郵件和封存聯絡人的能力都以 HTML 中的錨點形式編碼。如果其中一個操作不可用,或出現新的操作,它將在頁面刷新後以新的 HTML 片段形式出現。

這與胖客戶端方法形成對比,在胖客戶端方法中,例如,本地商店可能會與後端非同步同步,因此,HTML 並不是作為應用程式狀態的引擎,而是作為(有點粗糙的)UI 描述語言。

有點可笑的是,維基百科上關於 HATEOAS 的文章使用了 JSON,這不是一種自然的超媒體。如果您願意,您可以在 JSON 之上分層一些 REST 風格的行為,但是它在現實世界中很少有用,而且 HATEOAS 通常在 JSON API 中被忽略。這是合理的,因為 JSON API 主要對傳統客戶端-伺服器架構有用,並且不太適合 REST 風格。

#統一介面總結

這是 REST 的關鍵所在,也是這篇文章的關鍵所在。您可以繼續閱讀以了解有關 Fieldings 論文的更多細節和分析,但是這裡的核心要點是,REST 風格超媒體架構與傳統客戶端-伺服器架構之間存在著明顯的區別,而且這種區別主要圍繞著統一介面的概念,尤其是它們的自我描述性質。

同樣,不要在這裡陷入術語的泥潭,只需思考一下這個 HTML,以及它所具有的靈活性和創造力的奇蹟

<html>
  <body>
  <div>
    <div>
      Name: Joe Blow
    </div>
    <div>
      Email: joe@blow.com
    </div>
    <div>
      <a href="/contacts/42/edit">Edit</a>
      <a href="/contacts/42/email">Email</a>
      <a href="/contacts/42/archive">Archive</a>
    </div>
  </div>
</body>
</html>

#分層系統

您不需要對此了解太多,只需知道CDN 存在,並且您應該使用它們。

#按需程式碼

同樣,您不需要對此了解太多,只需知道 Javascript 存在,並且它是唯一可選的部分。

#第 5.2 節 - REST 架構元素

我不會像我們對其他章節那樣深入探討本節,因為它變得非常技術性,坦率地說,有點無聊和重複(正如人們可能從論文中所期望的那樣)。本節中的兩個重要思想是資源和表示。

#第 5.2.1 節 - 資源和資源識別符

從論文中

REST 中資訊的關鍵抽象是資源。任何可以命名的資訊都可以是資源:文件或圖像、時間服務(例如「洛杉磯今天的天氣」)、其他資源的集合、非虛擬物件(例如一個人)等等。

實際上,資源是可以通過 URL 定址的任何東西。當您存取 URL 時會發生什麼?

好吧,您會收到該資源的表示,以 HTTP 回應的形式,其中可能包含 HTML、指令等等。

#第 5.2.1 節 - 表示

我發現本節沒有太多的實際用途。有一些關於控制資料、媒體類型等等的內容,這些內容最終在需要時都值得學習,但它們並不是網路開發中常用的方面。

其餘的 5.2 節同樣沒有為普通使用者提供太多內容。

#第 5.3 節 - REST 架構觀點

這裡又出現了類似的狀況,我覺得本節對於一般的網頁開發者來說,沒有太多有用的新資訊,但有一個很大的例外:它闡述了 REST 的優點。

從論文中

REST 的客戶端-伺服器關注點分離簡化了元件實作、降低了連接器語義的複雜性、提高了效能調整的效率,並增加了純伺服器元件的可擴展性。分層系統的約束允許中介者(例如:代理伺服器、閘道器和防火牆)在通訊的各個點引入,而無需變更元件之間的介面,從而讓它們可以協助通訊轉換或透過大規模共享快取來提高效能。REST 透過限制訊息為自我描述來實現中介處理:請求之間是無狀態互動,使用標準的方法和媒體類型來指示語義和交換資訊,並且回應會明確指示是否可快取。

這些都是非常真實的,這也是為什麼網路如此成功並將持續成功的原因。

這些簡短的章節與對 REST 感興趣的非學術界人士無關。

#總結

總之,這就是 Roy Fielding 的博士論文第五章的簡短導覽,該論文給了我們 REST 這個詞。我已經專注於我認為網頁開發人員最需要理解的領域,並試圖傳達 REST 如何描述原始的網路模型。我認為統一介面的概念是 REST 中最重要和最有趣的方面,並且對於網頁開發人員理解是很有用的,因為它主要負責上述優點。

最後,我希望您能理解為何 REST 不適合用來描述目前使用的大多數 JSON API。

</>