Spring Boot,决定为 REST 和 JPA 分别创建 DTO 对象

Posted

技术标签:

【中文标题】Spring Boot,决定为 REST 和 JPA 分别创建 DTO 对象【英文标题】:Spring Boot, decision to create DTO object separately both for REST and JPA 【发布时间】:2016-05-16 06:36:24 【问题描述】:

我猜传统上,一个 RESTful Web 服务会使用一种类型的 DTO 对象进行 POJO/JSON 转换,并使用单独的 DTO 对象进行数据库实体/POJO 转换?

Spring Boot 应该更自以为是,更容易使用,但你还是会使用不同的 DTO 对象类型来表示 JSON 和数据库实体,还是直接将实体对象转换为 JSON?

【问题讨论】:

【参考方案1】:

让我谈谈我的看法。

起初,我认为您的问题与spring boot无关。 Spring boot 只是提供了一种花哨且轻量级的方式来启动应用程序,并允许以更简单的方式构建应用程序。 但是你仍然有你的休息控制器,从那时起,它对于任何其他类型的应用程序都没有太大区别。

因此,您实际上要问的是,维护 JSON 对象的抽象并将它们转换为业务逻辑实体对象,然后再将它们再次转换为数据库对象是否有意义,或者是否足以仅维护 2 个级别和放弃 Json 级别。

我认为答案是“视情况而定”。

首先,总的来说,目前的趋势是简化。所以也许它足以只维护 1 级对象。

这种方法有很多优点:

显然需要维护的代码更少 开发和测试速度(应检查 POJO,应测试转换器等) 执行速度 - 您无需在转换上浪费 CPU 时间。一种明显的暗示。 不太明显:内存消耗。假设您使用 DAO 返回的大量数据。假设它占用 10MB 内存(仅作为示例)。现在,如果您开始转换为业务实体,您将再花费 10MB,现在如果它的 A JSON 对象,那么它又是 10MB。关键是所有这些对象可能同时共存于内存中。当然,如果您正确实施一切,GC 可能会处理它们,但这是另一回事。

但是,这种简化有一个缺点。

总之,我称之为承诺

应用程序中有三种类型的 API。

您在 Web 服务级别承诺使用的 API - JSON 结构。 很可能各种客户端(根本不需要使用 JVM)针对您的 Web 服务运行并使用数据。所以他们真的希望你提供给定结构的 JSON 对象。

您的业务 API。如果您的业务逻辑层非常复杂,那么您可能拥有一个开发该逻辑的整个团队。因此,您通常在团队之间的 API 级别上工作。

DAO 级别 - 实际上与业务逻辑相同。

现在,如果您在某个级别更改该 API,会发生什么情况。是不是意味着所有的关卡都会被打破?

例子

可以说,我们不保持“JSON”级别。在这种情况下,如果我们在业务逻辑级别更改 API,JSON 也会自动更改。其余所有框架都会很乐意为我们转换对象,并且用户有可能获得其他数据。

另一个例子

假设您的 BL 层提供了一个 Person 实体,如下所示:

class Person 
      String firstName;
      String lastName;
      List<Language> languages;
   

   class Language 
     ...
   

现在,假设您有一个使用 REST 服务的 UI,该服务根据请求提供人员列表。如果 UI 中有 2 个不同的页面怎么办。仅显示人员(在这种情况下,提供一个人所说的语言列表是没有意义的)。 但是,您希望在第二页中获取完整信息。

因此,您最终会公开 2 个 Web 服务或通过一些参数使现有的一个复杂化(您拥有的这样的参数越多,它与其余的越不相似 :)) 也许分离在这里会有所帮助?我不知道。

底线。 我想说,只要你能在没有这种分离的情况下生活——就去做吧。它甚至可以用于相当大的项目。当然,它也适用于中小型项目。

如果您发现自己在修复问题上苦苦挣扎,并且您觉得这样的分离可以解决问题 - 请进行分离。

希望这有助于理解其中的含义并选择适合您的方法

【讨论】:

对于您提供的示例,4 年后您对此有何看法?您现在会推荐查询来过滤此类用例的集合吗?因为它看起来像是查询过滤的合适用例? (即.../persons?filter=languages

以上是关于Spring Boot,决定为 REST 和 JPA 分别创建 DTO 对象的主要内容,如果未能解决你的问题,请参考以下文章

如何决定为基于规则的系统创建哪些单元测试

Angular 可以决定为前端带来哪个模块,还是始终使用所有模块遍历整个应用程序?

使用spring-boot对rest服务进行访问控制

让 oauth2 与 spring-boot 和 rest 一起工作

JavaScript 如何决定为数值分配多大的内存?

spring boot下WebSocket消息推送