知識庫 / Web Services RSS 訂閱

HAL 與 HATEOAS 的關係與區別

Architecture,REST,Web Services
HongKong
7
03:34 AM · Dec 06 ,2025

1. 概述

Web API 隨着 REST (表意層傳輸) 的興起而迅速發展。基於 REST 的 API 允許開發者構建模塊化、標量化且鬆散耦合的強大 Web 應用程序。雖然 RESTful API 提供了一個堅實的基礎,但它們經常缺乏可發現性和可用性等關鍵要素。

這時,HATEOAS (狀態為引擎的超媒體) 和 HAL (超文本應用程序語言) 就能發揮重要作用。 如果沒有 HATEOAS,RESTful API 會與服務器緊密耦合,需要在客户端硬編碼端點。

在本教程中,我們將探索 HATEOAS 和 HAL 的概念、它們之間的關係以及它們的關鍵差異。

2. 理解 HATEOAS

HATEOAS 代表 Hypermedia as the Engine of Application State。要更深入地理解這個概念,首先我們需要理解 Hypermedia 的含義。 Hypermedia 是超文本的擴展,它包含文本鏈接和其他媒體類型,例如圖像、音頻和視頻。它允許通過啓用用户無縫地導航相關資源來實現豐富的交互。

HATEOAS 通過在響應中嵌入 Hypermedia 鏈接來增強 API 交互。這允許客户端在無需事先了解 API 結構的情況下,動態地導航和與資源交互。它促進鬆耦合,並允許 API 在獨立地演變。

這意味着客户端-服務器交互應該完全依賴於服務器響應中收到的 Hypermedia。每個服務器響應都包含鏈接,以指導客户端發現有關其他操作和資源的更多信息以及數據。

讓我們通過購物車的例子來更深入地瞭解 HATEOAS:

當客户端請求有關包含項目的購物車的詳細信息時,服務器會提供有關可能操作的相關鏈接:

GET /cart/12345 HTTP/1.1

HTTP/1.1 200 OK
{
  "cartId": 12345,
  "items": [
    {
      "id": 001,
      "name": "TV",
      "qty": 1,
      "amount": 4750
    }
  ],
  "totalAmount": 4750,
  "links": [
    {
      "rel": "self",
      "href": "/cart/12345"
    },
    {
      "rel": "addItem",
      "href": "/cart/12345/add"
    },
    {
      "rel": "removeItem",
      "href": "/cart/12345/remove"
    },
    {
      "rel": "checkout",
      "href": "/cart/12345/checkout"
    },
    {
      "rel": "clear",
      "href": "/cart/12345/clear"
    }
  ]
}

在上述示例中,客户可以添加或刪除更多項目、進入結算流程或清空購物車。所有這些操作都基於購物車中可用的項目。<em&nbsp;links</em> 鍵指示了可用的操作。現在,讓我們考慮一個空購物車示例:

GET /cart/987 HTTP/1.1

HTTP/1.1 200 OK
{
  "cartId": 987,
  "items": [],
  "totalAmount": 0.0,
  "links": [
    {
      "rel": "self",
      "href": "/cart/987"
    },
    {
      "rel": "addItem",
      "href": "/cart/987/add"
    },
    {
      "rel": "checkout",
      "href": "/cart/987/checkout"
    },
  ]
}

現在,客户可用的操作受到限制。客户可以向購物車添加商品或進入結算流程,但由於購物車已為空,因此他們無法清除或刪除商品。這段超文本告訴我們允許的操作以及不允許的操作。

3. 理解 HAL

HAL 是一種簡單格式,幫助開發者為 RESTful API 創建超媒體表示,支持 HATEOAS 原則。它定義了一種簡單格式,提供了一種便捷、一致的方式來在 REST API 中鏈接資源。

讓我們來了解一下 HAL 的關鍵概念。

3.1. 鏈接

HAL 允許在資源表示中包含超媒體鏈接。<em >_links </em > 屬性列出了與資源相關的鏈接。每個鏈接包含一個 <em >rel </em >(關係類型)和 <em >href </em >,客户端可以使用這些鏈接與 API 進行交互。<em >_links </em > 屬性還包含自鏈接,允許客户端直接訪問當前資源。

3.2. 嵌入式資源

如名稱所示,嵌入式資源表明其他資源包含在給定的 REST 資源中。<em >_embedded</em> 屬性可以包含相關資源。這允許客户端訪問相關信息,而無需發出任何額外的請求。

3.3. 狀態

HAL 使用 JSON 或 XML 對資源數據及其關聯鏈接進行編碼。

現在,我們來看一個不使用 HAL 的示例,API 的響應將如下所示:

{
  "cartId": 12345,
  "items": [
    {
      "id": 001,
      "name": "TV",
      "qty": 1,
      "amount": 4750
    }
  ]
}

上述示例並未提供任何相關資源的鏈接。現在,我們將添加 HAL 鏈接到響應中,使其成為符合 HAL 規範的示例:

{
  "_embedded": {
    "items": [
      {
        "id": 001,
        "name": "TV",
        "qty": 1,
        "amount": 4750,
        "_links": {
          "self": { "href": "/items/001" },
          "update": { "href": "/items/001/update" }
        }
      }
    ] 
  },
  {
    "_links": {
      "self": { "href": "/carts/12345" },
      "addItem": { "href": "/cart/12345/item" },
      "checkout": { "href": "/cart/12345/checkout" }
    }
  }
}

在上述示例中,主要數據位於 _embedded 屬性下。這裏,主要數據包含購物車中項目的列表,每個項目都有自己的 _links

4. HATEOAS 與 HAL 的關係

HATEOAS 和 HAL 在 RESTful API 設計中是密切相關的概念。HATEOAS 是一種 REST 原則,它鼓勵使用超媒體鏈接,以便客户端能夠動態地探索 API。另一方面,HAL 是一種具體的格式,它通過標準化資源及其連接的表示方式(通過鏈接)來幫助實現這一目標。

讓我們以之前討論的購物車的示例為例。當客户端請求有關包含商品的購物車的詳細信息時,服務器將返回一個 HAL 表示形式:

GET /cart/12345 HTTP 1.1

HTTP/1.1 200 OK

{
  "cartId": 12345,
  "items": [{
      "id": 001,
      "name": "TV",
      "qty": 1,
      "amount": 4500
    }],
  "totalAmount": 4500,
  "_links": {
      "self": { "href": "/cart/12345", "rel": "self" },
      "addItem": { "href": "/cart/12345/add", "rel": "addItem"},
      "checkout": { "href": "/cart/12345/checkout", "rel": "checkout" },
      "clear": { "href": "/cart/12345/clear" , "rel": "clearCart" }
  },
  "_embedded": {
      "offer": {
        "code": "DISCOUNT10",
        "discount": 10
      }
  }

在上述示例中,_links 部分提供基於當前資源狀態的客户端可執行的操作的超媒體鏈接。 rel 字段至關重要,因為它定義了鏈接所代表的操作(例如:self, addItem, checkout, 等)。它用於描述鏈接的含義以及客户端在 API 狀態的上下文中應該如何解釋它。

  _embedded 部分包含直接嵌入到主資源中的相關資源。它允許客户端在不發出額外請求的情況下訪問相關數據,從而減少網絡調用並提高效率。

資源的當前狀態被捕獲在響應中返回的實際數據中,例如項目和購物車總金額。

5. HATEOAS 和 HAL 的關鍵區別

讓我們來看看 HATEOAS 和 HAL 的關鍵區別:

方面 HATEOAS HAL
概念/格式 HATEOAS 是一種 REST 架構原則,它指導客户端通過遵循服務器提供的超媒體鏈接來發現可用的操作。 HAL 是一種用於以支持 HATEOAS 的方式表示資源的特定格式。
目的 HATEOAS 的目的是使 API 具有自我解釋性和易於導航。它減少了客户端需要先了解 API 結構的需求。 HAL 提供了一種清晰簡潔的方式來表示資源及其連接。它簡化了客户端解析和理解鏈接的過程。
實現 各種格式和技術,例如 JSON、XML,甚至 HAL 本身,都可以實現 HATEOAS。 HAL 專門使用 JSON 或 XML 結構化資源表示,強調鏈接。

6. 結論

在本文中,我們討論了 HATEOAS 和 HAL。 雖然 HATEOAS 闡述了 RESTful API 應該如何運行的一個原則,但 HAL 提供了一個具體的實現,簡化了 API 中的超媒體控件。 使用 HAL,開發人員可以輕鬆創建符合 HATEOAS 的 API,從而簡化客户端的資源發現和交互。

通過結合 HATEOAS 和 HAL,API 變得自描述且易於發現。 這導致客户端和服務器之間實現更好的解耦,允許 API 在一段時間內獨立演進。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.