domain-driven-design - 在 CQRS / 事件溯源中,是否所有数据都需要在命令和事件中?
问题描述
假设我有一个围绕 CQRS 事件溯源基础构建的应用程序:
- 由命令处理程序处理的应用程序调度命令 DTO
- 在传递和应用 Command 的数据时聚合引发事件
- 事件处理程序在收到他们感兴趣的事件时应用域逻辑和副作用(在我的情况下:他们进行预测)。
我的问题是:在步骤 1 和 3 中,我们是否需要在命令和事件 DTO 中提供所有信息,或者我们是否可以传递处理程序可以从数据库中获取的某些实体的 ID?
例子:
- 我有一个员工汇总
- RegisterEmployee命令_
- 员工注册事件
Employee Aggregate 有名字、姓氏、电子邮件和一些 VO,如地址、电话等。
它是Worker Entity的根,所以在我的应用程序的某个地方,我有一个 Employee Aggregate Id(UUID,生成的域)和 Worker Entity Id(整数,生成的数据库)的映射
指挥方:
在 RegisterEmployee 命令上,我是否需要传递为所有员工字段补充所需的所有数据?
然后我会有一个非常大的构造函数,其中包含名字、姓氏、电子邮件、地址、电话 1、电话 2 等。
我不能只给出命令中的基本字段(名字、姓氏、电子邮件)并传递 Worker 实体 ID,以便 RegisterEmployee 命令处理程序可以在数据库中检索要传递给聚合的电话和地址字段吗?
活动方:
在事件方面,如果我的 EmployeeRegistered 事件处理程序必须投影我的员工的读取模型,它是否需要拥有事件本身的所有信息才能构建读取模型?
或者我可以只将基本信息(名字、姓氏、电子邮件)和工作实体 ID 放入 EmployeeRegistered 事件的有效负载中,以便投影脚本本身加入数据库以检索一些复杂和隐藏的信息?
[编辑]
也许 RegisterEmployee 试图做太多事情,我应该:
- 发送一个简单的 RegisterEmployee 命令和基本的东西
- 调度其他一些命令,例如 AddEmployeeTelephone、AddEmployeeArress 等
但是在这种情况下,它是否违反了注册操作应该发生在同一事务中的原则?如果我的 RegisterEmployee 成功而其他人没有怎么办?我最终会得到一个不完整的员工注册流程吗?
[编辑 2]
嗨,博拉,你说得对。我的上下文发生在从遗留应用程序迁移到 cqrs 应用程序(至少某些部分)中。
所以我想让遗留应用程序做自己的事情,我只听数据库端的持久性事件,并从它们发送域命令。
这就是为什么我可以想象有一个命令持有“刚刚持久”的实体 ID,以便不复制命令中实体的字段,并减轻管道。
解决方案
域模型/设计中有问题。让我退后一步,概述理想的方式,以便您可以映射缺失的部分。
RegisterEmployee Command
包含所有数据输入Employee Aggregate
Employee Application Service
从前端接收命令Employee Application Service
初始化Employee Aggregate
,最好借助工厂方法Employee Aggregate
EmployeeRegistered Event
在成功验证和构造新的 Employee 对象时引发Employee Application Service
在Employee Repository
EmployeeRegistered Event
持久化事务成功后发送到消息代理EmployeeRegistered Event
包含订阅者所需的整个数据集Subscribers
对于这个事件可能在同一个限界上下文(BC)或不同的BCInterested Subscribers
赶上事件并Application Service
在自己的BC中致电相关人员Application services
初始化基础设施服务并执行交易(在您的情况下,这些是预测)
事件处理程序中不应有域逻辑。
推荐阅读
- python - 大于 RAM 的 Numpy 数组:写入磁盘还是核外解决方案?
- machine-learning - Keras Adam 优化器学习率超参数与单独计算的网络参数学习率有何关系?
- json - 尝试从 Bash 中的 JSON 文件加载消息负载以发送到 Slack 通道
- testing - 当配置为不运行时,带有标签的功能仍在运行
- bash - curl api 请求中的变量
- printing - ZPL 语言 - 无法旋转标签
- java - 如何使用具有多个 bean 定义的 Spring ObjectProvider
- java - 使用动态规划解决问题
- apache-kafka - 当我收到缺少所需参数“[topic]”的错误时,如何尝试阅读 kafka 中的主题
- postgresql - 如何在此查询中包含来自 case 语句的小于 where 语句?