我很好奇如何将来自多个聚合根的数据连接到事件源聚合根的读取模型中。我可以试着举一个简单的例子:
如果我有一个名为Cart的聚合根,它在它的事件流中支持以下事件(括号中的属性-请记住,这是一个简单的示例):
AddProductToCart(cartId: Int, productId: Int)
RemoveProductFromCart(cartId: Int, productId: Int)
AddUserLicenseToProduct(cartId: Int, productId: Int, userId: Int)
RemoveUserLicenseFromProduct(cartId: Int, productId: Int, userId: Int)
EmptyCart(cartId: Int)
当使用来自该事件流的数据来投影读取模型时,这是可以的。例如,我可以投影一个cart对象,如下所示:
Cart(cartId: Int, products: List[Product])
Product(productId: Int, userLicenses: List[UserLicense])
UserLicense(userId: Int)
但是如何将来自另一个上下文中的另一个聚合根的数据连接到这个购物车投影中呢?例如,如果我想使用位于另一个上下文中的Product聚合根目录中的数据来扩展读取模型。假设我想用productName和productType来扩展它。
考虑到我们在一个分布式系统中工作,其中Product和Cart将位于不同的服务/应用程序中。
我认为一种解决方案是在命令和事件中包含数据。但是,如果有更大的读取模型,其中包含来自多个聚合根的数据,那么这似乎不能很好地扩展。此外,还必须能够核化和重建读取模型。
我认为另一种解决方案是将数据从其他聚合根复制到其他应用程序/服务/上下文的存储中。例如,将productName和productType数据复制到购物车应用程序拥有的存储中,但不将其作为购物车事件流的一部分。购物车应用程序则必须侦听事件(例如ProductCreated、ProductNameChanged)以保持数据更新。我想这可能是一个可行的解决方案。
发布于 2019-05-29 03:47:06
每个绑定的上下文都应该是松散耦合的。我们在两个上下文中遇到了类似的问题。我们发现的解决方案是通过在这些文件中创建上下文之间的所有通信来使用工作流。其中,我们可以通过订阅一个事件处理程序来同步所需的模式。正如我们使用Elixir一样,我们使用的库是Commanded,它有自己的事件总线。
但在分布式系统中,您可以使用Apache Kafka。归根结底,我认为更简单的解决方案应该使您的模式尽可能保持干净(它还将帮助您遵守GDPR遵从性),并通过事件处理程序通过单独的层管理所有通信。
要以“现实生活”的方式看到这个解决方案,我可以向您推荐一个用Elixir构建的很好的示例存储库。
https://stackoverflow.com/questions/56292628
复制相似问题