CQRS/ES - 我理解正确吗?

CQRS/ES - do I understand It correctly?

我想总结一下我对CQRS/ES的了解。一段时间前我开始阅读这个主题,因为我是年轻的开发人员,所以我不理解这个概念的各个方面。我将尝试在一些示例流程中描述我对 CQRS 的理解。因此,定义该架构的一般步骤我们有以下流程:

  1. 用户向我们的控制器提出请求。在该控制器方法中,我们创建指定的 Command(例如 CreateOrder)并将其传递给 Handler.

  2. 全局消息总线(或处理程序)负责将命令路由到指定的命令处理程序。所以在这里我们将命令传递给 CreateOrderHandler

  3. 在处理程序中,我们创建 聚合根(在本例中为 OrderAggregate)并应用来自 事件存储。在 EventStore 中,我们只保留与指定聚合(由全局 id 定义)相关的事件数据。所以在这一步之后我们在当前状态下聚合。

  4. 创建聚合后,我们将命令传递给它,并在方法中验证命令是否可以执行。如果我们可以 运行 这个命令,我们将创建 Event(在本例中为 OrderCreated)。

  5. 如果没有任何异常我们把Event保存在EventStore中(我觉得NoSql DB简单易用,保存事件简单)

  6. 现在处理程序将保存的事件传递给我们的 Denormalizer class 这是创建 View Models 的网关.因此,如果非规范化器得到一些事件,它 updates/creates 我们应用程序中的所有 ViewModels。我们将 ViewModel 保存在单独的数据库中。

  7. 用户可以查询更新的视图模型。

所以我这个是我对CQRS/ES的理解的简化版。请在每一层上纠正我。我的问题是:

在第 4 步中我们创建了聚合,我们应该将这个聚合保存在数据库中吗?保持当前状态。我在这里错过了什么吗?我们创建聚合只是为了检查创建事件的可能性?

我应该有实体吗?如果我在第 5 步中正确,我可以更新聚合实体并在我的视图模型中使用它们。我在这里有最大的困惑。

感谢所有的回答 ;)

In 4-th step we created aggregate should we save this aggregate in DB? To keep current state. Am I missing something here? We created aggregate only for checking possibility to create event?

如果您使用 EventStore,ES 本身会保存您的聚合状态。您在命令处理程序中谈论 "create" 聚合,但通常最好说在命令处理程序中聚合是从 ES 中重新水合的。

聚合使用在 ES 中应用的命令(或其数据)和引发(域)事件来跟踪聚合的状态变化,并且相同的事件由事件处理程序(如非规范化器)处理。

在通常描述的流程中,我在第 3 步之前有一个命令验证步骤。 无论如何,前段时间我试图描绘components of a typical CQRS/ES flow;网上有好几个,也许有用

聚合状态源自应用于它的过去事件。所以你不需要存储它的状态,因为它是从事件流派生的。话虽如此,您可能希望创建快照以避免很长的事件历史记录。在设计快照系统之前,值得测试重新应用以前事件列表的速度有多快。

当您向聚合发出命令时,它会分两个阶段进行处理。第一阶段实质上是检查它是否可以运行。如果是这样,它会构建一个或多个事件来表示更改,然后再将它们应用于自身。这里的关键是事件的产生可以而且经常确实需要应用域逻辑。换句话说,它不仅仅是一个事件制作者。

如果您觉得它有帮助,我在我的博客上有一个典型 CQRS 应用程序的更详细的概述。您可以在这里找到它:CQRS – A Step-by-Step Guide to the Flow of a typical Application