领先一步
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<T> 现在是 EntityModel<T>
Resources<T> 现在是 CollectionModel<T>
PagedResources<T> 现在是 PagedModel<T>
作为副作用,ResourceAssembler 现在是 RepresentationModelAssembler,其方法现在是 toModel(…) 和 toCollection(…)。代码库中存在类似的更改来反映此变化。
许多 API 都围绕着 List<Link> 的概念,包括 RepresentationModel.getLinks()。我们现在返回的是增强型的 Links,而不是 Java List,以更轻松地组合、提取和合并链接。核心抽象 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 的一个片段。
通过将相关操作链接在一起,可以生成感知 affordances 的媒体类型,例如 HAL-FORMS(如下所示):
示例 2. 从 affordance API 生成的 HAL-FORMS 示例输出
{
"firstName" : "Frodo",
"lastName" : "Baggins",
"role" : "ring bearer",
"_links" : {
"self" : {
"href" : "https://: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
} ]
}
}
}
这种感知 affordances 的媒体类型提供了执行此资源更新所需的所有信息。
说到 HAL-FORMs,我们添加了*几种*新媒体类型:
但为什么只止步于此呢?虽然我们计划支持其他媒体类型,但这不应该阻止您创建自己的。我们引入了一个新的 SPI,允许您编写 自己的自定义媒体类型 并将其注册到 Spring HATEOAS,以便您可以将其与 Spring MVC、RestTemplate Bean、Spring WebFlux 和 WebClient Bean 一起使用。
您可能已经注意到,Spring 团队一直在更新其所有文档。我们也是!我们还开始 清理和检修内容,所以一定要看看。我们将在接下来的里程碑版本中进一步调整这些内容。有什么遗漏的吗?请告诉我们!有超过 80 个已关闭的问题,请务必查看。并告诉我们您的想法!
在讨论 Spring HATEOAS 时,不能不提 Spring Data REST。
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 找到构件。