HAL 和 HATEOAS 之间的关系和区别

在本文中,我们讨论了 HATEOAS 和 HAL。虽然 HATEOAS 概述了 RESTful API 应如何运行的原则,但 HAL 提供了一种具体的实现,可简化 API 中的超媒体控件。使用 HAL,开发人员可以轻松创建符合 HATEOAS 的 API,从而简化客户端的资源发现和交互。

通过结合 HATEOAS 和 HAL,API 变得具有自描述性和可发现性。这可以更好地分离客户端和服务器,使 API 能够随着时间的推移独立发展。

随着REST (表述性状态转移)的兴起,Web API 也迅速发展起来。基于 REST 的 API 允许开发人员构建功能强大的模块化、标量和松散耦合的 Web 应用程序。虽然RESTful API 提供了坚实的基础,但它们通常缺乏可发现性和可用性的基本要素。

这就是 HATEOAS(超媒体作为应用状态引擎)和 HAL(超文本应用语言)可以发挥重大作用的地方。如果没有 HATEOAS,RESTful API 就会与服务器紧密耦合,需要在客户端硬编码端点。

在本教程中,我们将探讨 HATEOAS 和 HAL 的概念、它们的关系以及主要区别。

了解 HATEOAS
HATEOAS 代表超媒体作为应用状态的引擎。要深入了解这个概念,我们首先需要了解超媒体的含义。超媒体是超文本的扩展,包括文本链接和其他媒体类型,例如图像、音频和视频。它允许用户无缝浏览相关资源,从而实现丰富的交互。

HATEOAS 通过在响应中嵌入超媒体链接来增强 API 交互。这使客户端能够动态导航并与资源交互,而无需事先了解 API 的结构。它促进了松散耦合,并允许 API 随着时间的推移独立发展。

这意味着客户端与服务器之间的交互应该完全依赖于服务器响应中收到的超媒体。来自服务器的每个响应都包含链接,这些链接可引导客户端发现数据之外的其他操作和资源。

让我们借助购物车示例进一步了解 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"
    }
  ]
}

在上面的例子中,客户可以添加或删除更多商品、继续结帐或清空购物车。所有这些操作都基于购物车中可用的商品。links键 表示可用的操作。现在,让我们考虑一个空购物车的例子:

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"
    },
  ]
}

现在,客户可进行的操作受到限制。客户可以将商品添加到购物车或继续结账,但无法清除或移除商品,因为购物车已经是空的。此超文本告诉我们哪些是允许的,哪些是不允许的。

了解 HAL
HAL 是一种简单的格式,可帮助开发人员为 RESTful API 创建超媒体表示,支持 HATEOAS 原则。它定义了一种简单的格式,可轻松、一致地在 REST API 中的资源之间建立超链接。

让我们来看看 HAL 的关键概念。

1. 链接
HAL 允许在资源表示中包含超媒体链接。_links属性列出与资源相关的链接。每个链接都包含一个rel(关系类型)和一个href,客户端可以使用它们与 API 交互。_links属性还包含一个自链接,允许客户端直接访问当前资源。

2. 嵌入资源
顾名思义,嵌入式资源表示其他资源包含在给定的 REST 资源中。_embedded属性可以保存相关资源。这允许客户端访问相关信息而无需发出任何额外请求。

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。

HATEOAS 与 HAL 的关系
在 RESTful API 设计方面,HATEOAS 和 HAL 是密切相关的概念。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 部分包含直接嵌入在主资源中的相关资源。它允许客户端无需发出额外请求即可访问相关数据,从而减少网络调用并提高效率。

资源的状态在响应中返回的实际数据中捕获,例如商品和购物车的总金额。

HATEOAS 和 HAL 之间的主要区别
让我们来看看 HATEOAS 和 HAL 之间的主要区别:


概念/格式:

  •  HATEOAS 是一种 REST 架构原则,它引导客户端通过遵循服务器提供的超媒体链接来发现可用的操作。    
  • HAL 是一种以支持 HATEOAS 的方式表示资源的特定格式。
目的  :
  •   HATEOAS 的目的是使 API 一目了然且易于导航。它减少了客户对 API 结构预先了解的需要。    
  • HAL 提供了一种清晰简洁的方式来表示资源及其连接。它简化了客户端解析和理解链接的过程。
执行  :
  •   各种格式和技术,例如 JSON、XML 甚至 HAL 本身,都可以实现 HATEOAS。    
  • HAL 专门使用 JSON 或 XML 来构造资源表示,强调链接。