使用Spring Data REST处理复杂的聚合根。

6

如果涉及到复杂的聚合根,我现在无法理解Spring Data REST的概念。如果我正确理解领域驱动设计(这是Spring Data的基本原则?),你只能通过存储库公开聚合根。

假设我有两个类PostComment。两者都是实体,Post有一个@OneToMany List<Comment> comments

由于Post显然是聚合根,我想通过PostRepository访问它。如果我创建@RepositoryRestResource public interface PostRepository extends CrudRepository<Post, Long>,那么对Post的REST访问就可以正常工作。

现在comments被渲染为内联,并且不像/posts/{post}/comments一样公开为子资源。只有当我引入CommentRepository时才会发生这种情况(如果我要坚持DDD,就不应该这样做)。

那么如何使用Spring Data REST处理复杂的领域对象呢?假设您必须检查所有评论总共不超过X个字符。这显然是由Post聚合根处理的不变量。您将在何处放置Post.addComment()的逻辑?如何将其他类公开为子资源,以便我可以访问/posts/{post}/comments/{comment}而不引入不必要的存储库?


1
请查看这篇关于处理聚合对象的帖子:https://dev59.com/dV8e5IYBdhLWcg3w2NRR - raner
1个回答

2
首先,如果Comment有一些限制条件,那么我会将这些约束放在构造函数调用中。这样,您不依赖于任何外部验证框架或机制来执行您的要求。如果您使用基于setter的解决方案(例如通过Jackson),那么也可以将这些约束放在setter中。
这样,Post就不必担心对Comment进行强制限制。
此外,如果您使用Spring Data REST并仅定义PostRepository,则评论的生命周期与集合根Post相关联,流程应该是:
1.获取Post及其Comment对象的集合。 2.将新的Comment追加到集合中。 3.PUT新的Post及其更新后的Comment对象到该资源中。
担心冲突?这就是标准HTTP头使用的条件操作。如果您向Post域对象添加了基于@Version的属性,则每次使用新的Comment更新给定的Post时,版本都会增加。
当您获取资源时,Spring Data REST将包括一个E-Tag头。这样,您的PUT可以通过HTTP If-Match: <etag>头进行条件化。如果其他人已更新实体,则会返回412状态代码,表示您应该刷新并重试。
注意:这些条件操作适用于PUTPATCHDELETE调用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接