Leo*_*nti 2 domain-driven-design cqrs event-sourcing
我们正在考虑在工作中实施 CQRS 模式,并且有几个关于验证的问题。
假设我们有 3 个聚合根:
User Business UserToBusinessRelationship当用户注册时,发送的事件将是:
UserCreated
BusinessCreated
UserAddedToBusiness
Run Code Online (Sandbox Code Playgroud)
需要验证事件,例如在用户和企业之间创建链接,用户和企业都应该被创建。
我看到两种方法。
前期验证:使用上次处理的快照和未处理的事件动态构建读取模型,并将其用于验证。
处理时验证:按原样接受事件/命令并在处理事件时进行验证。
第一种方法具有即时反馈,但它需要创建一个仅用于验证的最终读取模型。第二个更简单,但不会向消费者提供出现问题的反馈。
我在想这样的事情:当你发出一个事件时,你会得到一个 id,你以后可以用它来查询事件的状态。如果事件处理成功,你会得到“OK”,否则你会得到一个错误,告诉你出了什么问题。
这是一种有效的方法还是矫枉过正?消费者如何知道事件已被处理并且数据已准备好使用?
很好的问题 Leonti - 您可能会发现我关于在 CQRS 系统中进行验证的博客文章很有帮助。您可以在此处找到:如何验证 CQRS 应用程序中的命令。
请注意标题中的 CQRS 的重点是验证命令而不是事件。
为什么?
因为命令可以来自用户输入,因此不应该被信任。另一方面,事件是从域内部发出的并且可以信任。可能存在 CQRS 的实现,其中涉及离开系统边界的事件或接收并非源自系统内部的事件。在那些边缘情况下,应该小心。
另一个潜在的危险信号是您描述聚合的方式。在我看来(我不知道你的域,所以不能 100% 确定)它们更类似于数据库中的表而不是聚合。重要的是不要让您的持久性机制决定您的模型。
更具体地回到你的问题。
从广义上讲,有两种类型的验证。浅而深。肤浅的是缺少字段、有效的电子邮件地址等。深层是域概念发挥作用的时候。例如,需要货物的重量和表面验证,但货物是否适合承运人可能是一个领域概念。
您可能需要验证事物的存在。例如,企业或用户是否存在。虽然此验证很可能需要您访问数据库,但它仍然是肤浅的,因为它不太可能是一个明确的域概念。
无论如何,我希望这会有所帮助。