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

问题描述 投票:5回答:1

现在,如果涉及复杂的聚合根,我无法获得Spring Data REST背后的概念。如果我正确理解域驱动设计(这是AFAIK弹簧数据的基本原理吗?),那么只能通过存储库公开聚合根。

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

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

现在qazxsw poi呈现为内联,并且不像qazxsw poi那样暴露为子资源。只有当我引入comments时才会发生这种情况(如果我想坚持使用DDD,我不应该这样做)。

那么如何在复杂的域对象中正确使用Spring Data REST?假设你必须检查所有注释都不包含超过X个字符。这显然是由/posts/{post}/comments聚合根处理的一些不变量。你会把CommentRepository的逻辑放在哪里?如何将其他类公开为子资源,以便我可以在不引入不必要的存储库的情况下访问Post

spring rest spring-data-rest
1个回答
0
投票

对于初学者来说,如果对Post.addComment()有一些约束,那么我会把这个约束放在构造函数调用中。这样,您就不依赖任何外部验证框架或机制来强制执行您的要求。如果您被驱动到基于setter的解决方案(例如通过Jackson),那么您也可以将这些约束放在setter中。

这样,/posts/{post}/comments/{comment}不必担心强制对Comment施加约束。

此外,如果您使用Spring Data REST并且仅定义Post,由于注释的生命周期共同链接到聚合根Comment,因此流程应为:

  1. 获取PostRepository及其Post物品的集合。
  2. 将您的新Post添加到该集合中。
  3. 将新的Comment及其更新的Comment对象集合放到该资源中。

担心碰撞?这就是Post所使用的标准HTTP标头。如果你在Comment域对象中添加一个基于conditional operations的属性,那么每次使用新的@Version更新给定的Post时,版本都会增加。

获取资源时,Spring Data REST将包含一个E-Tag标头。

这样,您的PUT可以使用HTTP If-Match:<etag>标头进行条件化。如果其他人更新了实体,您将获得412状态代码,表示您应该刷新并重试。

注意:这些条件操作适用于PUT,PATCH和DELETE调用。

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