领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多尊敬的 Spring 社区成员们,我们自豪地宣布 Spring HATEOAS 1.0 的第一个里程碑版本发布。Spring HATEOAS 已经开发了近七年时间。它最初是 Spring MVC 的一个小扩展,后来成为 Spring Data REST 的基础,并且一直是 Spring MVC 应用程序中基于超媒体 API 的基本构建块。
我们从社区收到了很多关于更高级功能的反馈,最终决定将这些功能集成到库中。此外,我们在实际应用中积累了大量的使用经验,我们认为应该抓住机会在 1.0 版本中反映这些经验教训。
以下是摘要
包设计和领域模型语言的全面检修。
将 Java 8 和 Spring Framework 5.1 作为基线。
通过 affordances API 提供高级超媒体支持 (HAL-FORMS、Collection+JSON、UBER)。
超媒体支持 SPI,用于插入自定义媒体类型实现。
用于 Spring WebFlux 的 `LinkBuilder` 实现。
完全改进了参考文档。
让我们详细了解其中的一些功能。
在发布 1.0 之前,我们抓住机会重新评估了包结构以及我们在领域类型中公开的术语。这导致与我们的 0.x 版本相比,出现了一些相当显著的变化。
最根本的变化是 Spring HATEOAS 不创建资源。这是 Spring MVC/Spring WebFlux 所做的。我们创建的是与供应商无关的超媒体表示。因此,我们重命名了这些核心类型
`ResourceSupport` 现在是 `RepresentationModel`
`Resource
`Resources
`PagedResources
作为副作用,`ResourceAssembler` 现在是 `RepresentationModelAssembler`,其方法现在是 `toModel(...)` 和 `toCollection(...)`。整个代码库中都有类似的变化反映了这一变化。
许多 API 都围绕 `List` 概念展开,包括 `RepresentationModel.getLinks()`。现在,我们返回的是 `Links`(而不是 Java 列表),它得到了显著增强,使组合、提取和合并链接更加容易。核心抽象 `LinkBuilder`、`EntityLinks`、`RelProvider`、`LinkDiscoverer` 分别被分组到 `server` 和 `client` 包中。
听起来很复杂?别担心,我们编写了一个脚本,它将尽最大努力将您的大部分代码迁移到新的类型和导入语句。它可能无法涵盖所有内容,但应该大大简化迁移过程。
此版本中最关键的功能之一是对 Spring WebFlux 和响应式编程的支持。这包括:
响应式地构建链接。
向 WebFlux 端点提供超媒体。
支持 WebFlux 的 `WebClient` 来使用超媒体。
Spring HATEOAS 带有 `WebFluxLinkBuilder`,因此您可以响应式地构建链接。它会自动获取服务器托管的基本 URI,并将其与您端点的路径合并。
示例 1. 响应式地创建链接和 affordances
import static org.springframework.hateoas.server.reactive.WebFluxLinkBuilder.*;
@GetMapping("/employees")
public Mono<CollectionModel<EntityModel<Employee>>> all() {
var controller = methodOn(WebFluxEmployeeController.class);
return Flux.fromIterable(EMPLOYEES.keySet())
.flatMap(id -> findOne(id))
.collectList()
.flatMap(resources -> linkTo(controller.all()).withSelfRel() (1)
.andAffordance(controller.newEmployee(null)) (2)
.andAffordance(controller.search(null, null))
.toMono() (3)
.map(selfLink -> new CollectionModel<>(resources, selfLink)));
}
指向具有 Reactor 类型的 WebFlux 端点的链接。
以一种领域友好的方式添加 affordances(有关详细信息,请参见下面的内容)。
返回一个 `Mono`,以便您可以执行任何额外的 Reactor 操作。
假设此控制器托管在http://example.com,则预期将提供一个包含指向http://example.com/employees的链接的超媒体文档。
除了响应式地构建链接之外,当您返回基于`RepresentationModel`的类型时,您的 WebFlux 端点现在将呈现超媒体,无论它是否包装在 Reactor 类型中。
我们在过去两年中一直在开发Affordances。我们从 Escalon 的@dschulten和 HDIV Security 的@anderruiz团队那里获得了宝贵的经验,了解如何收集元数据以呈现比已支持的 HAL 更详细地描述资源交互的更高级媒体类型。您在上面的 WebFlux 端点中看到了该元数据收集 API 的片段。
通过将相关的操作链接在一起,可以生成支持 affordance 的媒体类型,例如 HAL-FORMS(如下所示)
示例 2. 由 affordance API 生成的 HAL-FORMS 示例输出
{
"firstName" : "Frodo",
"lastName" : "Baggins",
"role" : "ring bearer",
"_links" : {
"self" : {
"href" : "https://127.0.0.1:8080/employees/1"
}
},
"_templates" : {
"default" : {
"title" : null,
"method" : "put",
"contentType" : "",
"properties" : [ {
"name" : "firstName",
"required" : true
}, {
"name" : "lastName",
"required" : true
}, {
"name" : "role",
"required" : true
} ]
},
"partiallyUpdateEmployee" : {
"title" : null,
"method" : "patch",
"contentType" : "",
"properties" : [ {
"name" : "firstName",
"required" : false
}, {
"name" : "lastName",
"required" : false
}, {
"name" : "role",
"required" : false
} ]
}
}
}
这种支持 affordance 的媒体类型提供了执行此资源更新所需的所有信息。
说到 HAL-FORMs,我们添加了 *几个* 新的媒体类型:
但是为什么止步于此呢?虽然我们计划支持其他媒体类型,但这不应该阻止您创建自己的媒体类型。我们引入了一个新的 SPI,允许您编写您自己的自定义媒体类型,并将其注册到 Spring HATEOAS,以便您可以将其与 Spring MVC、`RestTemplate` bean、Spring WebFlux 和 `WebClient` bean 一起使用。
如果您没有注意到,Spring 团队一直在升级其所有文档。我们也是!我们还开始清理和改进内容,所以一定要浏览一下。我们将在接下来的里程碑版本中进一步调整这些内容。有什么遗漏的吗?请告诉我们!超过80 个已关闭的问题,请务必查看一下。并让我们知道您的想法!
如果不提到 Spring Data REST,就不能讨论 Spring HATEOAS。
Spring HATEOAS 的所有这些更改都已被 Spring Data REST 的最新快照版本吸收和适配。总体计划是让 Spring Data - Release train **Moore** 升级到 Spring HATEOAS 1.0。这意味着诸如 affordances 和新的媒体类型之类的功能将成为 Spring Data REST 的一部分。
Spring HATEOAS 1.0 现在基于 Spring Framework 5.1。这意味着诸如 **Forwarded** 头部处理之类的功能已委托给 Spring Framework 来管理。如果您的应用程序前面有代理服务器正在发送正确的头部,并且您的 Spring HATEOAS 驱动的 API 突然没有重写 URI,则需要配置头部处理。
如果您使用的是 Spring Boot,则只需要:
server.use-forward-headers=true
如果您没有使用 Spring Boot,则必须配置类似以下内容:
@Bean
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
var filter = new FilterRegistrationBean<>();
filter.setFilter(new ForwardedFilter());
return filter;
}
更多详细信息,请查看 Spring Framework 的 Forwarded 头部过滤器。
查看下面的项目链接。
这是一个里程碑版本,您可以在 https://repo.spring.io/libs-milestone 找到构件。