【问题标题】:How to handle relationships between aggregate roots in resolvejs如何处理resolvejs中聚合根之间的关系
【发布时间】:2021-09-09 05:50:47
【问题描述】:

我无法弄清楚如何处理 resolvejs 中聚合根之间关系的一些基本问题。基本问题是我如何处理关系的完整性?为此,您似乎需要同时了解双方的知识,但在写入方面似乎不允许这样做。

设置如下:我正在尝试构建一个用户管理工具,我有两个聚合根,User 和 Organisation。我需要允许两者独立存在并在它们之间定义access 关系(即用户可以访问任意数量的组织)。

如果关系属于User,我可以在User 聚合上创建一个类似grantAccessToOrganisation 的命令,该命令采用organisationId,但这会引发几个问题。如何确保提供的organisationId 是真实的?似乎它需要在命令处理程序中发生,但由于该命令属于 User 聚合,我无权访问 Organisation 聚合。另外,当组织被删除时,我应该如何处理?似乎这应该对所有有权访问它的用户产生副作用,但我似乎没有在写入端进行查询的好方法。

【问题讨论】:

    标签: domain-driven-design relationship event-sourcing resolvejs


    【解决方案1】:

    尽量不要将聚合视为传统系统中的“实体”。选择聚合根作为事务和一致性边界。

    这意味着给定聚合的所有命令都是连续的,其状态是一致的,这意味着您可以确定您的命令已应用于预期的聚合状态,并且其他用户或进程没有进行任何更改。

    作为一个极端的例子,您甚至可以拥有一个聚合“系统”,您可以访问整个系统状态。但这意味着状态的大小将是巨大的,每个命令都会锁定整个系统。

    因此,请选择足够大以控制其交易且足够小以不阻塞其他交易的聚合。

    在您的示例中,我可以猜测 User 更多的是关于身份、登录名、个人资料、头像 - 诸如此类。它可以在没有组织知识和访问权限的情况下生存。组织是处理访问权限的集合体,而更改访问权限是影响单个组织的事务。

    所以我会将grantAccess 命令发送给组织,而不是您示例中的用户。但当然这取决于其他要求,我在这里可能是错误的。

    此外,总会有一些可以通过 saga 实现的聚合间业务规则。例如,如果禁用用户登录,则其访问权限将在 30 天后删除。 Saga 是一项长期运行的业务事务,可能会影响多个聚合。

    【讨论】:

    • 谢谢你们。我可以看到如何转换关系。我认为问题仍然存在。我将如何编码特定用户可以访问特定组织的事实?一旦命令到达,如何确保它是一个真正的用户和组织?就像您说的那样,一个答案是确保它们都处于相同的聚合中,但似乎并不难想象由于其他原因而不理想的场景。
    • 我会使用 saga 来撤销已删除和不存在的用户的访问权限,因此在 grantAccess 命令中,您无需检查用户聚合。这是一个问题的一般概述danielwhittaker.me/2014/11/22/…
    • 好的,我想我理解这一点,因为删除案例的撤销访问权限。但是对于授予用户访问组织的情况,我可能让用户聚合接受在其有效负载中带有组织 ID 的命令,并假设存在这样的组织,以及其他管理谁可以访问的规则对什么都满意。然后响应随后的授权访问事件,将运行一个 saga,如果实际上没有这样的组织,那么它可能会发出第二个撤销访问命令。我无法决定这是否是个好主意。
    • 我要说的是,您不能在命令处理程序中始终同步访问其他聚合门的状态,因此请使用足够大的聚合-它们的状态将包含更多信息。其他一切都是异步的——你在发送命令之前检查组织和用户是否存在,如果在这短时间内发生了变化——你处理 saga 中的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    相关资源
    最近更新 更多