CQRS 和事件溯源 - 保存命令而不是事件?

CQRS & Event Sourcing - save commands instead of events?

我是 CQRS 和事件溯源的新手,但也许有人可以帮助我。

简而言之:我将一个命令对象带到一个聚合之类的东西中。聚合生成一个事件,该事件存储在存储库中。现在我可以使用此事件将聚合重建为当前状态。对吗?

现在我要考虑的是:保存命令不是更容易吗?如果我有一个创建命令和五个更新命令,我可以通过在一个空聚合上执行这六个命令来重建我的聚合。我不需要处理命令和事件来生成聚合。

这些事件也可以用作域事件,但我不需要它们来进行事件溯源。

使用事件溯源而不是我的方法有什么优势?

好问题。有几个原因。我只会介绍两个。第一个更概念化,第二个更具体一些。

从概念上讲,您正在存储因命令而更改的内容。到底发生了什么。随着应用程序在其生命周期中的进展,您可能会改变处理命令的方式。您甚至可以更改创建的事件。所以如果你只有命令,你不能保证你将能够恢复聚合的状态。

如果您需要重播您的事件,您也会遇到问题。假设您需要根据过去的事件创建一个新的阅读模型。但如果你没有它们,你将无法做到。此外,在重建聚合或创建新的读取模型时,您也不希望系统实际执行命令让它们执行的所有操作。例如,假设在特定命令的正常处理过程中发送了一封电子邮件。您不希望每次重建聚合时都发送该电子邮件。

希望这是有道理的。

另外 - 注意 'create' 'read' 更新命令。这听起来像是代码的味道。查看 https://danielwhittaker.me/2014/10/18/6-code-smells-cqrs-events-avoid/

我不会回答事件溯源的优势是什么,但我认为重要的是要考虑你想要实现什么,命令来自哪里以及除了事件之外你什么时候需要存储命令。

你想达到什么目的? 如果您想将服务版本 1.0 在生产中收到的所有命令应用到新开发的版本 1.1,那么您需要这些命令。例如,您可以这样做来测试服务功能或性能。

命令从何而来? 命令是基于事件创建的,由 UI,由其他不发布事件的应用程序创建,...

除了事件之外,何时存储命令? 如果目标是模拟与生产环境相同的环境,那么您需要记录所有输入。所以你需要所有的命令。如果您不存储来自 UI 的命令,那么您将不会拥有这些命令。因此,如果没有生成命令的事件或者您没有存储它,那么存储命令可能会有好处。为了保持一致性,您可以存储包含命令以及来自请求的其他数据的 HttpRequestReceivedEvent,而不是存储 ChangeUserCommand。