Bean 验证和一致的值对象

问题描述 投票:0回答:2

我当前的项目正在使用领域驱动设计,这是一个基于Java的Spring Boot REST-API。因此,应该不可能创建不一致的值对象,而我的问题就在那里。

我想实现 bean 验证来为我的消费者提供清晰的错误响应。但是,bean 验证无法验证所有必需字段,因为该过程将被我的值对象的现有构造函数验证中断。如果传递了无效数据,则会抛出异常,并且 Bean 验证过程将立即结束。

我的值对象中的构造函数验证是强制性的,无法删除。

(我在类级别使用@Validated,在复杂对象上使用@Valid,在原始构造函数参数上使用@Pattern/NotNull...)

一种可能的解决方案可能是在反序列化期间使用自定义反序列化器和值对象的默认构造函数创建不一致的值对象。

可悲的是,我不知道如何实现这一点。在这种情况下如何触发 Bean 验证?

java spring spring-boot jackson domain-driven-design
2个回答
0
投票

我在这里看到的问题是您的请求与域对象的验证混合在一起。

您应该将代表域对象的 bean 业务逻辑与从外部世界传入的数据分开。

例如:

您需要一个在请求对象中传入控制器的数据集。 它可以是 Json 映射到 java 对象。该对象可以通过 jakarta 库进行验证。在这里您检查@NonNull、@SomeOther 字段验证。

当这部分过程中验证出现错误时,您可以创建包含验证错误的响应。

请记住,这是请求数据的错误,而不是域 bean 或进程的错误。

在下一步中正确验证请求数据后,您应该将此请求传递给工厂/构造函数以创建域对象,或者您应该为流程处理程序创建包含数据的命令。

在创建之前,应根据定义的 DOMAIN 规则验证此域对象或命令。

我提出了我的解决方案。也可以用其他方式完成,但我认为这是最简单的方法。

您还可以查看此 github 存储库:https://github.com/krzysztofslusarski/jug-hex 实践中显示 ddd 的地方(没有restAPI,但这只是一个输入接口,所以可以用其他东西代替)。


0
投票

如果它是一个选项,请不要使用 bean 验证。

我喜欢我的对象具有“零时间无效状态”,因此所有内容都在构造函数中进行验证。

© www.soinside.com 2019 - 2024. All rights reserved.