一尘不染

REST API-是否有DTO?

spring

我目前正在为一个项目创建REST-API,并且一直在阅读有关最佳实践的文章。许多人似乎反对DTO,只是公开域模型,而其他人似乎认为DTO(或用户模型或任何你想称呼的东西)是不好的做法。我个人认为这篇文章很有道理。

但是,我还了解了DTO的所有额外映射代码,域模型可能与其DTO对应对象100%相同的缺点等。

我们主要创建API,以便其他客户端可以使用数据,但是,如果操作正确,我们也将尽可能地将其用于自己的Web GUI。

问题是我们可能不想将所有域数据公开给其他客户端用户。许多数据仅在我们自己的Web应用程序中才有意义。另外,我们可能不希望在所有场景中公开有关某个对象的所有数据,尤其是与其他对象的关系等等。例如,如果我们公开特定对象的列表,则不一定要公开整个对象层次结构。这样就不会暴露对象的子对象,而是可以通过链接(阴影)来发现它。

我应该如何解决这个问题?我正在考虑在我们的域模型上使用Jackson混合来控制在不同情况下将公开哪些数据。还是考虑到DTO的缺点和争议,我们是否应该一路使用DTO?


阅读 574

收藏
2020-04-11

共1个答案

一尘不染

为什么要在REST API中使用DTO
DTO代表d ATA 牛逼转让(BOT)Ø bject。

创建此模式的目的非常明确:将数据传输到远程接口,就像Web服务一样。这种模式非常适合REST API ,从长远来看,DTO将为你提供更大的灵活性。

该代表的车型领域的应用代表了和模型通过你的API处理的数据是(或者至少应该是)不同的关注点,应该去耦彼此。在应用程序域模型中添加,删除或重命名字段时,你不想破坏API客户端。

当你的服务层在域/持久性模型上运行时,你的API控制器应在一组不同的模型上运行。例如,随着域/持久性模型的发展以支持新的业务需求,你可能希望创建API模型的新版本以支持这些更改。随着新版本的发布,你可能还想弃用旧版本的API。当事物分离时,这是完全有可能实现的。

仅提及公开DTO而不是持久性模型的一些好处:

将持久性模型与API模型分离。

DTO可以根据你的需求进行定制,当仅公开持久性实体的一组属性时,它们非常有用。你将不需要诸如@XmlTransient和的注释,@JsonIgnore以避免某些属性的序列化。

  • 通过使用DTO,你将避免在持久性实体中出现批注,也就是说,持久性实体不会因​​与持久性无关的批注而肿。

  • 在创建或更新资源时,你将完全控制要接收的属性。

  • 如果使用的是Swagger,则可以使用@ApiModel和@ApiModelProperty注释来记录你的API模型,而不会弄乱你的持久性实体。

  • 你可以为每个API版本使用不同的DTO。

  • 映射关系时,你将具有更大的灵活性。

  • 你可以为不同的媒体类型使用不同的DTO。

  • 你的DTO可以具有HATEOAS的链接列表。那种事情不应该添加到持久性对象中。使用Spring HATEOAS时,你可以扩展DTO类RepresentationModel(以前称为ResourceSupport)或将其包装EntityModel(以前称为Resource)。

处理样板代码

你无需手动将持久性实体映射到DTO,反之亦然。有很多映射框架,你可以用它来做到这一点。例如,看看基于注释的MapStruct,它可以作为Maven注释处理器使用。它在CDI和基于Spring的应用程序中都能很好地工作。

你可能还需要考虑龙目岛生成gettersetter方法,equals()hashcode()toString()为你的方法。

2020-04-11