Spring HATEOAS 中的资源是否替换了 DTO?

Does Resource in Spring HATEOAS replace the DTOs?

我正在 Spring 中构建 REST API。所以直到现在我只有阅读服务(GET)。为此,我使用 Spring HATEOAS 添加引用子元素的链接。

现在我想添加一些编写REST-Services。通常 DTO 在 REST 服务中使用,然后将其映射到域模型。

所以我的问题是:我们能否像下面的示例那样只使用来自 Spring HATEOAS 的资源而不使用 DTO?还是资源用于其他用途而我仍然需要 DTO?

@PostMapping
public ResponseEntity<String> saveProduct(@RequestBody ProductResource product) {
  ...
}

我会说 Spring HATEOAS 不会取代 DTO:它建立在 DTO 之上。所以你可以让你的 DTO class 扩展 ResourceSupport or wrap it with Resource<T>.

自从 Spring HATEOAS 1.0.0 于 2019 年 9 月下旬发布以来,ResourceSupport and Resource<T> have been renamed to RepresentationModel and EntityModel<T> respectively. Quoting the documentation:

Representation models

The ResourceSupport / Resource / Resources / PagedResources group of classes never really felt appropriately named. After all, these types do not actually manifest resources but rather representation models that can be enriched with hypermedia information and affordances. Here’s how new names map to the old ones:

  • ResourceSupport is now RepresentationModel
  • Resource is now EntityModel
  • Resources is now CollectionModel
  • PagedResources is now PagedModel

然而,重要的是保持域模型与 API 模型分离。

代表您的应用程序的模型和代表您的API处理的数据的模型是(或至少应该)不同的关注点。当您从应用程序域模型中添加、删除或重命名字段时,您不想破坏 API 客户端。

虽然您的服务层在 domain/persistence 模型上运行,但您的 API 控制器应该在一组不同的模型上运行。例如,随着 domain/persistence 模型的发展以支持新的业务需求,您可能希望创建新版本的 API 模型来支持这些变化。随着新版本的发布,您可能还想弃用 API 的旧版本。当事物解耦时,完全可以实现。

为了尽量减少将域模型转换为 API 模型(反之亦然)的样板代码,您可以依赖 MapStruct. And you also could consider using Lombok 等框架来生成 getter、setter、equals()hashcode()toString() 方法。