是否有关于应如何应用 CQRS 和 CQRS 问题的硬性定义

Is there a hard definition of how CQRS should be applied and CQRS questions

我在理解 CQRS 模式的核心是什么时遇到了一些困难,这意味着红线是什么,当越过这些红线时,我们没有实现 CQRS 模式。

我清楚地理解了 CQS 模式。

假设我们使用 CQRS 实现微服务,没有事件源。

1) 第一个问题是,CQRS 模式是否仅适用于客户端I/O?意思是,希望我做对了,例如,客户端使用写入数据库 A 的控制器进行更新,但通过查询写入数据库 B 的控制器进行读取,(B 最终会更新,并且可能会使用发送的事件从多个模型中聚合信息A 的控制器)。

或者,这不是关于客户端,而是关于任何东西,例如另一个微服务读/写?如果是后者,定义谁是导致隔离的 reader / 作者的真正界限是什么? 这可能与 DDD 中的域有关吗?

这是我心中的一个重要问题,因为没有它,CQRS 只是一种相互依赖,模型 B 被模型 A 更新,而不是相反。为什么这不会从模型 B 传播到模型 C?

我还读过一些文章,指出有些人通过使用一个命令服务和一个查询服务来实现 CQRS,这使事情变得更加复杂。

2) 和第一个问题类似,为什么有些参考文献把事件说成好像是CQRS的命令?在我看来,这使 CQRS 变得复杂,因为从技术上讲,我们可以通过一个请求事件请求一个服务 "Hey please give me the information X",并且该服务可以响应一个包含有效负载的事件,从而有效地进行查询。这是一个硬性规定,还是只是一个例子来说明,我们可以使用事件进行更新,我们可以使用 REST 进行查询?

3) 如果在大多数情况下我写入模型 A,然后从模型 B 读取,但在某些情况下我直接从模型 A 读取怎么办? 我破坏了 CQRS 吗? 如果我的查询需求很简单,这种情况下是否应该复制模型A?

4) 如果如问题 1) 所述,我从模型 A 读取数据以发出事件,生成模型 B,但随后我喜欢从模型 B 读取一些信息,因为它很有价值,因为它是聚合的,为了生产模型C? 我破坏了 CQRS 吗? 在这种情况下,填充模型 B 的控制器在做什么,例如如果它也发出事件来填充模型 C?反正它只是一个命令,因为它不是查询的部分,所以我们仍然应用 CQRS?

此外,如果我们从模型 A 读取以发出事件,以生成模型 B,但是当我们生成模型 B 时,我们发出事件以发送客户端通知。那还是 CQRS 吗?

5) CQRS 什么时候坏了? 如果我有一个从模型 B 读取的控制器,但也发出更新模型 A 的消息,是吗?

最后,如果那个控制器,例如一个 REST 控制器,从模型 B 读取并同时发出一条消息来更新模型 A,但不包含从模型 B 读取的任何信息,(因此操作是二合一的,但它不使用来自 B 的信息来更新A),那还是CQRS吗?

而且,如果更新模型 A 的 REST 控制器还 returns 一些从 A 读取的信息给客户端,这会破坏 CQRS 吗?如果这只是一个 id 怎么办?如果id不是从A读取的,而只是随机生成的参考号怎么办?在这种情况下是否存在问题,因为 REST 控制器更新,但也 returns 给用户一些东西?

非常感谢您的耐心回复,可见我还是比较迷茫,正在学习中!

Is there a hard definition of how CQRS should be applied and CQRS questions

是的,从 Greg Young 开始。

CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value). -- Greg Young 2010

它 "just a pattern" 源于这样一个事实,即对查询有效的数据表示通常不是对跟踪更改有效的模式。例如,使用 RDBMS 存储业务数据可能是我们维护数据完整性的最佳选择,但对于某些类型的查询,我们可能希望在图形数据库中使用该数据的副本。

why do some references speak of events as if they are the Commands of CQRS

HandleEvent是一个命令。 CommandReceived 是一个事件。读者(和作者!)很容易混淆所描述的上下文。它们都是 "just" 消息,一个或另一个的语义实际上取决于消息传播的方向相对于消息中信息的权限。

例如,如果我在电子商务网站上填写表格并提交;相应的消息是 OrderSubmitted 事件吗?还是 PlaceOrder 命令?两种拼写都可能是正确的,具体取决于您选择如何模拟订购流程。

What if, in most cases I write to model A, and I read from model B, but in some cases I read directly from model A? Am I breaking CQRS?

如果您从写入模型读取,CQRS 警察不会来找您。在许多架构中,业务逻辑在无状态组件中执行,并且依赖于从某些存储设备读取 "current" 状态——换句话说,支持写入通常需要读取。

悲观写入模型以支持读取用例是我们试图避免的事情。

还有:课程用马。将 CQRS 的使用限制在您可以从中获利的情况下是完全合适的。当 GET/PUT 单个模型的语义起作用时,您应该更喜欢它们而不是单独的模型进行读取和写入。