【发布时间】:2019-12-16 22:11:40
【问题描述】:
假设我有一个围绕 CQRS 事件溯源基础构建的应用程序:
- 由命令处理程序处理的应用程序调度命令 DTO
- 在传递和应用 Command 的数据时聚合引发事件
- 事件处理程序在收到他们感兴趣的事件时应用域逻辑和副作用(在我的例子中:他们进行预测)。
我的问题是:在步骤 1 和 3 中,我们是否需要在命令和事件 DTO 中提供所有信息,或者我们可以传递一些实体的 ID,然后处理程序可以从数据库中获取?
示例:
- 我有一个员工集合
- RegisterEmployee 命令
- EmployeeRegistered事件
Employee Aggregate 包含名字、姓氏、电子邮件和一些 VO,例如地址、电话等。
它是 Worker Entity 的根,所以在我的应用程序的某处我有一个 Employee Aggregate Id(UUID,域生成)和 Worker Entity Id(整数,数据库生成)的映射
命令端:
在 RegisterEmployee 命令中,我是否需要传递所有需要的数据来补充所有 Employee 的字段?
然后我将有一个非常大的构造函数,其中包含名字、姓氏、电子邮件、地址、电话 1、电话 2 等。
我不能只给出命令中的基本字段(名字、姓氏、电子邮件)并传递 Worker 实体 ID,以便 RegisterEmployee 命令处理程序可以在数据库中检索到要传递给聚合的电话和地址字段吗?
活动方:
在事件方面,如果我的 EmployeeRegistered 事件处理程序必须投影我的员工的读取模型,它是否需要在事件本身中包含所有信息才能构建读取模型?
或者我可以在 EmployeeRegistered 事件的有效负载中只放入基本信息(名字、姓氏、电子邮件)和 Worker 实体 ID,以便投影脚本本身加入数据库以检索一些复杂和隐藏的信息?
[编辑]
也许 RegisterEmployee 试图做太多事情,我应该:
- 用基本的东西发送一个简单的 RegisterEmployee 命令
- 发送一些其他命令,例如 AddEmployeeTelephone、AddEmployeeAdrress 等
但是在这种情况下,它是否违反了注册操作应该发生在同一事务中的原则?如果我的 RegisterEmployee 成功而其他人没有怎么办?我最终会得到一个不完整的员工注册流程吗?
[编辑 2]
嗨,Bola,你说得对。我的上下文发生在从遗留应用程序迁移到 cqrs 应用程序(至少某些部分)中。
所以我想让遗留应用程序做自己的事情,我只在 db 端监听持久性事件,并从它们发送域命令。
这就是为什么我可以想象有一个命令持有“刚刚持久”的实体 ID,以便不重复命令中实体的字段,并减轻管道。
【问题讨论】:
-
你能澄清一下吗:我不能只给出命令中的基本字段(名字、姓氏、电子邮件)并传递工作人员实体 ID,以便 RegisterEmployee 命令处理程序可以在数据库中检索电话和传递给聚合的地址字段? - 假设您是第一次注册员工(比如说从某种形式),所有关于员工的数据都应该作为表单数据来吗?您将从哪个数据库获取数据?
-
很好的评论,缺少一些信息。我编辑了我的问题。
标签: domain-driven-design cqrs event-sourcing