搜索聚合根 ID
Search for aggregate root id
我尝试将事件溯源引入我的项目,但不确定如何以错误较少的方式完成特定的事情。
这是一个“会计”系统,但主要关注的是交易,而不是账户。问题是我收到了提款或存款等事件,授权持有created/decreased/increased/expired/reversed,授权持有已解决(这意味着很快就会有提款事件),以及带有交易细节的事件。
在我的例子中聚合根是一个事务。它可以创建(通过授权保留或直接使用 withdrawal/deposit 事件)和更新。
这里有什么我不能完全理解。我通过 authorization hold created
获得了第一个事件。在此事件中,我只有此授权保留的金额和密钥。密钥来自外部系统,显然。因此,我使用 UUID4 生成了一个新的 TransactionId,创建了一个新的聚合根,添加了第一个事件,并将其持久化。接下来,我收到一个事件 withdrawal was created
。此事件有金额、交易密钥等一些其他数据,并且可能在外部系统中有一个具有授权持有参考的密钥。如果它没有这样的密钥,那么我只需生成一个新的 TransactionId 并存储一个新的聚合。但是如果有这样的键,那么我需要加载在 authorization hold created event
.
期间创建的先前聚合
问题是取款事件没有来自我的系统的聚合根 ID。如果我错了请纠正我,但我考虑以下流程
- 检查
withdrawal created
事件是否引用了授权保留
- 如果引用不在事件中
- 使用
withdrawal created
事件 创建一个新的交易聚合
- 如果事件有引用
- 找到在其负载中具有此值的
authorization hold created
事件
- 获取已创建事件的聚合 ID
- 加载此聚合 ID 的所有事件并构建聚合根
- 将
withdrawal created
添加到聚合并保留它
是否正确?
使问题更抽象和通用。如果我没有在传入消息中获得聚合根 ID,那么是否 ok/valid 根据我在传入数据的值上构建的某些标准在事件存储中搜索特定的聚合根 ID?
您不能t/shouldn从聚合中查询事件存储的某些条件,相反,客户端应该首先查询读取端以查看相关聚合是否存在,然后将这些 ID 添加到聚合命令。
看到“外系统”的概念,你肯定来到了集成区。通常,内部限界上下文不希望耦合到外部系统。你的例子很好地说明了这个问题。您有来自外部系统的 ID,在处理这些外部事件并相应地生成内部命令时,您需要将其映射到您的内部 ID。
这项工作是在我们称为“反腐败层”(来自 Blue Book 的模式)的地方完成的。它需要保留外部系统 ID 和您的内部 ID 之间的所有映射。
在最简单的情况下,ACL 只是某种读取模型。例如,当您收到 authorization hold created 并为 hold 生成新的 id 时,您将映射存储在某处,然后在收到取款事件时使用此存储查询映射的 id。
但是,如果这个外部系统在您的上下文中是一个众所周知的概念(而且它可能是),您可能希望在您的域模型中包含这些外部 ID,并将它们命名为 externalXXXId
。然后,通过将这些初始事件作为键值对投影到某个数据库,您将能够在收到第二个事件时找到此映射,然后相应地加载您的聚合(或创建一个新聚合)。
我尝试将事件溯源引入我的项目,但不确定如何以错误较少的方式完成特定的事情。
这是一个“会计”系统,但主要关注的是交易,而不是账户。问题是我收到了提款或存款等事件,授权持有created/decreased/increased/expired/reversed,授权持有已解决(这意味着很快就会有提款事件),以及带有交易细节的事件。
在我的例子中聚合根是一个事务。它可以创建(通过授权保留或直接使用 withdrawal/deposit 事件)和更新。
这里有什么我不能完全理解。我通过 authorization hold created
获得了第一个事件。在此事件中,我只有此授权保留的金额和密钥。密钥来自外部系统,显然。因此,我使用 UUID4 生成了一个新的 TransactionId,创建了一个新的聚合根,添加了第一个事件,并将其持久化。接下来,我收到一个事件 withdrawal was created
。此事件有金额、交易密钥等一些其他数据,并且可能在外部系统中有一个具有授权持有参考的密钥。如果它没有这样的密钥,那么我只需生成一个新的 TransactionId 并存储一个新的聚合。但是如果有这样的键,那么我需要加载在 authorization hold created event
.
问题是取款事件没有来自我的系统的聚合根 ID。如果我错了请纠正我,但我考虑以下流程
- 检查
withdrawal created
事件是否引用了授权保留 - 如果引用不在事件中
- 使用
withdrawal created
事件 创建一个新的交易聚合
- 使用
- 如果事件有引用
- 找到在其负载中具有此值的
authorization hold created
事件 - 获取已创建事件的聚合 ID
- 加载此聚合 ID 的所有事件并构建聚合根
- 将
withdrawal created
添加到聚合并保留它
- 找到在其负载中具有此值的
是否正确?
使问题更抽象和通用。如果我没有在传入消息中获得聚合根 ID,那么是否 ok/valid 根据我在传入数据的值上构建的某些标准在事件存储中搜索特定的聚合根 ID?
您不能t/shouldn从聚合中查询事件存储的某些条件,相反,客户端应该首先查询读取端以查看相关聚合是否存在,然后将这些 ID 添加到聚合命令。
看到“外系统”的概念,你肯定来到了集成区。通常,内部限界上下文不希望耦合到外部系统。你的例子很好地说明了这个问题。您有来自外部系统的 ID,在处理这些外部事件并相应地生成内部命令时,您需要将其映射到您的内部 ID。
这项工作是在我们称为“反腐败层”(来自 Blue Book 的模式)的地方完成的。它需要保留外部系统 ID 和您的内部 ID 之间的所有映射。
在最简单的情况下,ACL 只是某种读取模型。例如,当您收到 authorization hold created 并为 hold 生成新的 id 时,您将映射存储在某处,然后在收到取款事件时使用此存储查询映射的 id。
但是,如果这个外部系统在您的上下文中是一个众所周知的概念(而且它可能是),您可能希望在您的域模型中包含这些外部 ID,并将它们命名为 externalXXXId
。然后,通过将这些初始事件作为键值对投影到某个数据库,您将能够在收到第二个事件时找到此映射,然后相应地加载您的聚合(或创建一个新聚合)。