我很难理解CQRS模式的真正含义,其核心是什么,当交叉时,我们没有实现CQRS模式的红线是什么。
我清楚地了解CQS模式。
假设我们使用CQRS实现微服务,而没有事件源。
1)第一个问题是,CQRS模式仅适用于客户端I / O吗?意思是,希望我理解正确,例如,客户端使用写入数据库A的控制器进行更新,但由查询写入数据库B的控制器进行读取,(B最终会被更新,并且可能会使用由发送的事件汇总来自多个模型的信息A)的控制者。
或者,这与客户端无关,而是什么,例如另一个微服务读/写?如果是后者,那么究竟是什么界定了导致种族隔离的读者/作家是谁呢? 这可能与DDD中的域有关吗?
在我看来,这是一个重要的问题,因为没有它,CQRS只是模型B正在由模型A更新而不是相反的相互依赖。为什么不将其从模型B传播到例如模型C?
我还阅读了一些文章,指出有些人通过拥有一个Command Service和一个Query Service来实现CQRS,这使这更加复杂。
2)与第一个问题类似,为什么某些引用将事件视为CQRS的命令?这使CQRS复杂化,因为从技术上讲,通过一个请求事件,我们可以请求服务“嘿,请给我信息X”,并且该服务可以响应包含有效负载的事件,从而有效地进行查询。这是一个硬性规则,还是仅说明一个例子,我们可以使用事件进行更新,也可以使用REST查询?
3)如果在大多数情况下我写给模型A,然后从模型B读取,但是在某些情况下,我直接从模型A读取,该怎么办? 我要打破CQRS吗? 如果我的查询需求非常简单怎么办,在这种情况下应该复制模型A吗?
4)如果(如问题1)所述,我从模型A读取以发出事件并生成模型B,但随后我想从模型B读取一些信息,因为它很有价值,因为它被汇总起来是很有价值的生产C型? 我要打破CQRS吗? 在这种情况下,填充模型B的控制器是做什么的?是否还会发出事件以填充模型C?还是因为它不是查询的一部分,还是因为它只是一个Command,所以我们仍然应用CQRS吗?
此外,如果我们从模型A读取事件以产生事件,以产生模型B,但是在产生模型B时,我们产生事件以发送客户通知呢?还是CQRS吗?
5)CQRS何时中断? 如果我有一个控制器可以从模型B读取数据,但还会发出一条消息来更新模型A,是吗?
最后,如果是该控制器,例如REST控制器,从模型B读取并同时发出一条消息以更新模型A,但不包含从模型B读取的任何信息,因此操作是二合一的,但它不使用从B来的信息进行更新A),那还是CQRS吗?
然后,如果更新模型A的REST控制器也将一些信息从A读取回客户端,这会破坏CQRS吗?如果这只是一个身份证怎么办?如果没有从A读取ID,而只是随机生成的参考号,该怎么办?在这种情况下是否存在问题,因为REST控制器会更新,但还会将某些内容返回给用户?
非常感谢您的耐心等待,因为我仍然感到困惑,而且我正在学习中!
答案 0 :(得分:1)
对于如何应用CQRS和CQRS问题是否有明确的定义
是的,从Greg Young开始。
CQRS只是在以前只有一个的两个对象的创建。根据方法是命令还是查询来进行分隔(与Meyer在“命令和查询分隔”中使用的定义相同,命令是使状态发生变化的任何方法,而查询是返回值的任何方法)。 -Greg Young 2010
这是“只是一种模式”,其源于这样一个事实,即对查询有效的数据表示形式通常不是对跟踪更改有效的模式。例如,使用RDBMS存储业务数据可能是维护数据完整性的最佳选择,但是对于某些类型的查询,我们可能希望在图形数据库中使用该数据的副本。
为什么某些引用将事件视为CQRS的命令
HandleEvent
是命令。 CommandReceived
是一个事件。读者(和作者!)很容易混淆所描述的上下文。它们都是“纯”消息,一个或另一个的语义实际上取决于消息相对于消息中信息授权的行进方向。
例如,如果我在电子商务网站上填写表格并提交;相应的消息是OrderSubmitted
事件吗?还是PlaceOrder
命令?两种拼写方式都是正确的,具体取决于您选择如何对订购过程进行建模。
如果在大多数情况下我写给模型A,然后从模型B读取,但是在某些情况下,我直接从模型A读取,该怎么办?我在打破CQRS吗?
如果您从写入模型中读取信息,CQRS警察将不会追随您。在许多体系结构中,业务逻辑是在无状态组件中执行的,并且将依赖于从某些存储设备读取“当前”状态-换句话说,要支持写入,通常需要进行读取。
模拟写模型以支持读取用例是我们要避免的事情。
也:赛马。将CQRS的使用限制在您可以从中获利的情况下是完全适当的。当单个模型的GET / PUT语义起作用时,您应该希望它们将模型分开以进行读写。