Domain driven design 事件验证

Domain driven design 事件验证,domain-driven-design,cqrs,event-sourcing,Domain Driven Design,Cqrs,Event Sourcing,我们正在考虑在工作中实现CQRS模式,并且有几个关于验证的问题 假设我们有3个聚合根: 用户 业务 UserToBusinessRelationship 当用户注册时,发送的事件将是: UserCreated BusinessCreated UserAddedToBusiness 需要验证事件,例如,为了在用户和业务之间创建链接,应该同时创建用户和业务 我看到两种方法 前期验证:使用上次处理的快照和未处理的事件动态构造读取模型,并将其用于验证 处理时验证:按原样接受事件/命令,并在处理事件

我们正在考虑在工作中实现CQRS模式,并且有几个关于验证的问题

假设我们有3个聚合根:

  • 用户
  • 业务
  • UserToBusinessRelationship
当用户注册时,发送的事件将是:

UserCreated
BusinessCreated
UserAddedToBusiness
需要验证事件,例如,为了在用户和业务之间创建链接,应该同时创建用户和业务

我看到两种方法

  • 前期验证:使用上次处理的快照和未处理的事件动态构造读取模型,并将其用于验证

  • 处理时验证:按原样接受事件/命令,并在处理事件时进行验证

  • 第一种方法有即时反馈,但它需要创建一个最终的读取模型以进行验证。第二个更简单,但不会向消费者反馈出问题

    我在想这样的事情:当你发出一个事件时,你会得到一个id,以后你可以用它来查询事件的状态。如果事件处理成功,您将得到“OK”,否则您将得到一个错误,告诉您出了什么问题


    这是一种有效的方法还是一种过激的手段?消费者如何知道事件已被处理,数据已准备好使用?

    好问题Leonti-你可能会发现我关于CQRS系统验证的博客文章很有帮助。您可以在这里找到:

    请注意,从标题中可以看出,CQRS的重点是验证命令,而不是事件

    为什么?

    因为命令可以来自用户输入,因此不应被信任。 另一方面,事件是从域内发出的,可以信任。可能存在涉及离开系统边界的事件或接收非源于系统内的事件的cqr的实现。在这些边缘情况下,应小心

    另一个潜在的危险是您描述聚合的方式。在我看来(我不知道你的领域,所以不能100%确定),它们更像数据库中的表,而不是聚合。重要的是不要让持久性机制支配模型

    更具体地回到你的问题上来

    一般来说,有两种类型的验证。肤浅而深刻。表面的是缺少字段、有效的电子邮件地址等。深层的是域概念起作用的时候。e、 g.需要货物重量,并进行表面验证,但货物是否适合承运人可能是一个领域概念

    你可能需要针对事物的存在进行验证。是否存在业务或用户。虽然此验证很可能需要您访问数据库,但它仍然是肤浅的,因为它不太可能是一个明确的域概念


    无论如何,我希望这能有所帮助。

    这里有两个主要方面:

  • 在CQR中,您有命令和查询。事件来自哪里?假设您也指事件源,但是,在使用命令时,您在客户机上执行一些验证,一些在命令处理程序中,一些在域模型中(聚合不变量和约束)。这个特定的示例看起来像是在客户端和命令处理程序中验证的

  • 请记住,由于在三个不同的聚合上有三个不同的操作,因此需要有三个事务。这意味着,如果其中一个无法完成,您的系统将进入无效状态。您或者需要重新考虑聚合边界以拥有一个聚合根,或者考虑使用其他技术,如事件驱动策略、sagas(流程管理器)或路由单(sagas)


  • 当然,
    UserToBusinessRelationship
    听起来更像是一个RDBMS多对多链接表,而不是一个聚合表,但我对您的域一无所知。

    您所说的“事件验证”是什么意思?在CQRS中,仅验证命令;在接受它们并生成事件后,这些事件必须被接受,它们被认为是非常有效的,它们代表了已经发生的事实。您的问题的答案可能是: