6.2 启用超媒体
到目前为止,创建的 API 是相当基本的,但是只要使用它的客户机知道 API 的 URL 模式,它就可以工作。例如,客户端可能被硬编码,知道它可以向 /design/recent 接口发出 GET 请求来获得最近创建的 tacos 列表。同样地,它可能是硬编码的,以知道它可以将该列表中的任何 taco 的 ID 附加到 /design 接口中,以获得特定 taco 资源的 URL。
使用硬编码的 URL 模式和字符串操作在 API 客户机代码中很常见。但是请想象一下,如果 API 的 URL 模式改变了,会发生什么。硬编码的客户端代码相对于 API 已经过时了,因此会被破坏。硬编码 API url 并在其上使用字符串操作会使客户端代码变得兼容性弱。
超媒体作为应用程序状态的引擎(HATEOAS),是一种创建自描述 API 的方法,其中从 API 返回的资源包含到相关资源的链接。这使客户机能够在对 API 的 url 了解最少的情况下引导 API。相反,它理解 API 提供的资源之间的关系,并在遍历这些关系时使用对这些关系的理解来发现 API 的 url。
例如,假设一个客户端请求一个最近设计的 tacos 列表。在它的原始形式,没有超链接,最近的 tacos 列表将在客户端以 JSON 的形式接收,看起来像这样(为了简洁起见,除了列表中的第一个taco 外,其他都被剪掉了):
1
[
2
{
3
"id": 4,
4
"name": "Veg-Out",
5
"createdAt": "2018-01-31T20:15:53.219+0000",
6
"ingredients": [
7
{"id": "FLTO", "name": "Flour Tortilla", "type": "WRAP"},
8
{"id": "COTO", "name": "Corn Tortilla", "type": "WRAP"},
9
{"id": "TMTO", "name": "Diced Tomatoes", "type": "VEGGIES"},
10
{"id": "LETC", "name": "Lettuce", "type": "VEGGIES"},
11
{"id": "SLSA", "name": "Salsa", "type": "SAUCE"}
12
]
13
},
14
...
15
]
Copied!
如果客户端希望在 taco 本身上获取或执行其他 HTTP 操作,则需要(通过硬编码)知道可以将 id 属性的值附加到路径为 /design 的 URL。同样,如果它希望对其中一个成分执行 HTTP 操作,它需要知道它可以将成分的 id 附加到路径为 /ingredients 的 URL。在这两种情况下,都需要在路径前面加上 http://https:// 和 API 的主机名。
相反,如果使用超媒体启用了 API,则该 API 将描述自己的 url,从而使客户端无需进行硬编码。如果嵌入了超链接,那么最近创建的 tacos 列表可能与下面的列表类似。
程序清单 6.3 包含超链接的 taco 资源列表
1
{
2
"_embedded": {
3
"tacoResourceList": [
4
{
5
"name": "Veg-Out",
6
"createdAt": "2018-01-31T20:15:53.219+0000",
7
"ingredients": [
8
{
9
"name": "Flour Tortilla", "type": "WRAP",
10
"_links": {
11
"self": { "href": "http://localhost:8080/ingredients/FLTO" }
12
}
13
},
14
{
15
"name": "Corn Tortilla", "type": "WRAP",
16
"_links": {
17
"self": { "href": "http://localhost:8080/ingredients/COTO" }
18
}
19
},
20
{
21
"name": "Diced Tomatoes", "type": "VEGGIES",
22
"_links": {
23
"self": { "href": "http://localhost:8080/ingredients/TMTO" }
24
}
25
},
26
{
27
"name": "Lettuce", "type": "VEGGIES",
28
"_links": {
29
"self": { "href": "http://localhost:8080/ingredients/LETC" }
30
}
31
},
32
{
33
"name": "Salsa", "type": "SAUCE",
34
"_links": {
35
"self": { "href": "http://localhost:8080/ingredients/SLSA" }
36
}
37
}
38
],
39
"_links": {
40
"self": { "href": "http://localhost:8080/design/4" }
41
}
42
},
43
...
44
]
45
},
46
"_links": {
47
"recents": {
48
"href": "http://localhost:8080/design/recent"
49
}
50
}
51
}
Copied!
这种特殊风格的 HATEOAS 被称为 HAL(超文本应用语言)这是一种简单且常用的格式,用于在 JSON 响应中嵌入超链接。
虽然这个列表不像以前那样简洁,但它确实提供了一些有用的信息。这个新的 tacos 列表中的每个元素都包含一个名为 _links 的属性,该属性包含用于客户端引导的 API 超链接。在本例中,tacos 和 ingredients 都有引用这些资源的自链接,整个列表都有一个引用自身的 recents 链接。
如果客户端应用程序需要对列表中的 taco 执行 HTTP 请求,则不需要了解 taco 资源的 URL 是什么样子的。相反,它知道请求自链接,该链接映射到 http://localhost:8080/design/4。如果客户想要处理特定的成分,它只需要遵循该成分的自链接。
Spring HATEOAS 项目为 Spring 提供了超链接支持。它提供了一组类和资源汇编器,可用于在从 Spring MVC 控制器返回资源之前向资源添加链接。
要在 Taco Cloud API 中启用超媒体,需要将 Spring HATEOAS starter 依赖项添加到构建中:
1
<dependency>
2
<groupId>org.springframework.boot</groupId>
3
<artifactId>spring-boot-starter-hateoas</artifactId>
4
</dependency>
Copied!
这个启动程序不仅将 Spring HATEOAS 添加到项目的类路径中,还提供了自动配置来启用 Spring HATEOAS。需要做的就是重新设计控制器以返回资源类型,而不是域类型。首先,将超级媒体链接添加到 /design/recent 的 GET 请求中,用于返回的最近的 tacos 列表。
最近更新 2yr ago
复制链接