Spring HATEOAS 1.0 M1 发布

发布 | Greg L. Turnquist | 2019年3月5日 | ...

尊敬的 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` 现在是 `EntityModel`

  • `Resources` 现在是 `CollectionModel`

  • `PagedResources` 现在是 `PagedModel`

作为副作用,`ResourceAssembler` 现在是 `RepresentationModelAssembler`,其方法现在是 `toModel(...)` 和 `toCollection(...)`。整个代码库中都有类似的变化反映了这一变化。

许多 API 都围绕 `List` 概念展开,包括 `RepresentationModel.getLinks()`。现在,我们返回的是 `Links`(而不是 Java 列表),它得到了显著增强,使组合、提取和合并链接更加容易。核心抽象 `LinkBuilder`、`EntityLinks`、`RelProvider`、`LinkDiscoverer` 分别被分组到 `server` 和 `client` 包中。

听起来很复杂?别担心,我们编写了一个脚本,它将尽最大努力将您的大部分代码迁移到新的类型和导入语句。它可能无法涵盖所有内容,但应该大大简化迁移过程。

Spring WebFlux 支持

此版本中最关键的功能之一是对 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)));
}
  1. 指向具有 Reactor 类型的 WebFlux 端点的链接。

  2. 以一种领域友好的方式添加 affordances(有关详细信息,请参见下面的内容)。

  3. 返回一个 `Mono`,以便您可以执行任何额外的 Reactor 操作。

假设此控制器托管在http://example.com,则预期将提供一个包含指向http://example.com/employees的链接的超媒体文档。

除了响应式地构建链接之外,当您返回基于`RepresentationModel`的类型时,您的 WebFlux 端点现在将呈现超媒体,无论它是否包装在 Reactor 类型中。

Affordances

我们在过去两年中一直在开发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 Data REST,就不能讨论 Spring HATEOAS。

Spring HATEOAS 的所有这些更改都已被 Spring Data REST 的最新快照版本吸收和适配。总体计划是让 Spring Data - Release train **Moore** 升级到 Spring HATEOAS 1.0。这意味着诸如 affordances 和新的媒体类型之类的功能将成为 Spring Data REST 的一部分。

Spring Framework 5.1 支持

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 头部过滤器

查看下面的项目链接。

链接:项目页面 | GitHub | 问题

这是一个里程碑版本,您可以在 https://repo.spring.io/libs-milestone 找到构件。

获取 Spring 新闻

关注 Spring 新闻

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring在一个简单的订阅中提供对 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部