【问题标题】:Read model with data from multiple aggregate roots (different contexts)使用来自多个聚合根(不同上下文)的数据读取模型
【发布时间】:2019-05-24 12:22:32
【问题描述】:

我很好奇如何在事件源聚合根的读取模型中连接来自多个聚合根的数据。可以尝试举个简单的例子:

如果我有一个名为 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(cartId: Int, products: List[Product])

Product(productId: Int, userLicenses: List[UserLicense])
UserLicense(userId: Int)

但是如何将来自另一个上下文中另一个聚合根的数据连接到此购物车投影中。例如,如果我想使用来自另一个上下文中的 Product 聚合根的数据来扩展读取模型。假设我想用 productName 和 productType 扩展它。

考虑到我们在分布式系统中工作,其中 Product 和 Cart 将存在于不同的服务/应用程序中。

我想一种解决方案是将数据包含在命令和事件中。但是,如果一个具有来自多个聚合根的数据的更大读取模型,这似乎不能很好地扩展。还必须能够核对和重建读取模型。

我想另一种解决方案是将数据从其他聚合根复制到其他应用程序/服务/上下文的存储中。例如,将 productName 和 productType 数据复制到属于 Cart 应用程序的存储中,但不让它成为 Cart 事件流的一部分。然后,购物车应用程序必须侦听事件(例如 ProductCreated、ProductNameChanged)以保持数据更新。我想这可能是一个可行的解决方案。

【问题讨论】:

    标签: domain-driven-design cqrs event-sourcing


    【解决方案1】:

    每个有界上下文都应该是松散耦合的。我们在两个上下文中遇到了类似的问题。我们找到的解决方案是通过在这些文件中创建上下文之间的所有通信来使用工作流。我们可以通过订阅事件处理程序来同步所需的模式。由于我们使用 Elixir,我们一直使用的库是 Commanded,它有自己的 Event Bus。

    但在分布式系统中,您可以使用 Apache Kafka。归根结底,我认为更简单的解决方案应该使您的架构尽可能干净(它也将帮助您遵守 GDPR 合规性)并通过事件处理程序通过单独的层管理您的所有通信。

    要以“真实”的方式查看此解决方案,我可以向您推荐一个使用 Elixir 构建的出色示例存储库。

    https://leanpub.com/buildingconduit/read

    【讨论】:

      【解决方案2】:

      这个问题还涉及事件驱动架构,而不仅仅是事件溯源。我认为您已经涵盖了从事件制作者那里获取相关数据的大多数选项。

      另一个选项是事件包含尽可能少的来自相关有界上下文的数据。至少这将是一个标识符。但是,在大多数情况下,应该对某些数据进行非规范化以使其有意义。例如,将产品描述非规范化为Cart 和最终的Order 会很有帮助,尤其是当有人在我做出选择后更改描述时。描述可能会从Blue pen 更改为Red pen,这将大大改变我打算购买的内容。在这种情况下,Shopping BC 中的 Product 可能由包含 IdDescription 的值对象表示。

      如果您现在想增加只读数据,我们只能选择从源 BC 检索它。这可以使用一些 API(Rest/ACL)在读取模型中完成,然后保存数据。为了使其更具容错性,可以选择消息传递/服务总线基础架构来处理附加数据的检索和相关读取模型记录的更新。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-18
        • 1970-01-01
        相关资源
        最近更新 更多