我是CQRS / ES世界的新手,我有一个问题。我正在开发一个使用事件源和CQRS的开票Web应用程序。
我的问题是 - 根据我的理解,进入系统的新命令(让我们说ChangeLineItemPrice)应该通过域模型,以便它可以被验证为合法命令(例如,检查是否此订单项实际存在,价格不违反任何商业规则等)。如果一切顺利(命令未被拒绝) - 则会创建并存储相应的事件(例如LineItemPriceChanged)
我还没有得到的是在尝试应用命令之前如何将这个聚合保留在内存中。如果我在系统中有一百万张发票,每次我想申请一个命令时,我应该播放整个历史记录吗?我是否总是在没有任何验证的情况下保存事件,并在构建视图模型/投影时进行验证?
如果我误解了过程的任何部分,我将非常感谢您的反馈。
感谢您的帮助!
答案 0 :(得分:19)
你并不孤单,这是一种常见的误解。让我先回答验证部分:
在这种系统中有两种类型的验证。第一种是您查找有效电子邮件地址,仅限数字或必填字段的类型。此类型在命令发出之前完成。包含这些问题的命令不应该作为命令引发(对于你可以在域方检查的带和括号,但这不是域关注,你最好只是防止这种情况)。
下一种类型的验证是 域关注的时候。这可能是你提到的那种你检查价格在一组指定参数范围内的东西。这是商业人士理解,做和能够表达的领域概念。
下一阶段是域应用状态更改并引发相关事件。然后将这些内容保留并成功发布,用于应用程序的其余部分。
所有这一切都可以通过内存中的聚合来完成。这些操作与处理命令的域服务协调。它加载聚合,应用所有它的过去事件(或加载快照),然后发出命令。在命令成功时,它会请求所有新的未提交事件并尝试保留它们。成功后,它会发布新事件。
如您所见,它仅加载特定聚合的事件。即使有很多事件,这个过程也很快。如果性能存在问题,则可以采用一些策略,例如将聚合保留在内存中或快照中,以便应用。
关于验证事件的最后一点。因为它们只能由您的聚合生成,所以它们是值得信赖的。
祝你好运 - 我希望他们有所帮助!