Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CQRS - is it allowed to call the read side from the write side?

Tags:

cqrs

I started with reading about CQRS and I'm little confused.

Is it allowed to call the read side within the write side for getting additional informations?

http://cqrs.nu/Faq/command-handlers here they say it is not allowed, but in the cqrs journey code I found that they call a service 'IPricingService' which internally uses a DAO service class.

So what I must do to get additional informations inside my aggregation root?

like image 266
Thomas Geulen Avatar asked Jul 10 '15 10:07

Thomas Geulen


3 Answers

CQRS Journey should not be seen as a manual. This is just a story of some team fighting their way to CQRS and having all limitations of using only Microsoft stack. Per se you should not use your read model in the command handlers or domain logic. But you can query your read model from the client to fetch the data you need in for your command and to validate the command.

Since I got some downvotes on this answer, I need to point, that what I wrote is the established practice within the pattern. Neither read side accesses the write side, not write side gets data from the read side.

However, the definition of "client" could be a subject of discussion. For example, I would not trust a public facing JS browser application to be a proper "client". Instead, I would use my REST API layer to be the "client" in CQRS and the web application would be just a UI layer for this client. In this case, the REST API service call processing will be a legitimate read side reader since it needs to validate all what UI layer send to prevent forgery and validate some business rules. When this work is done, the command is formed and sent over to the write side. The validations and everything else is synchronous and command handling is then asynchronous.

UPDATE: In the light of some disagreements below, I would like to point to Udi's article from 2009 talking about CQRS in general, commands and validation in particular.

like image 136
Alexey Zimarev Avatar answered Oct 21 '22 09:10

Alexey Zimarev


The CQRS FAQ (http://cqrs.nu/Faq) suggests:

"How can I communicate between bounded contexts?

Exclusively in terms of their public API. This could involve subscribing to events coming from another bounded context. Or one bounded context could act like a regular client of another, sending commands and queries."

So although within one BC its not possible to use read-side from write-side and vice-versa, another bounded context or service could. In essence, this would be acting like a human using the user interface.

like image 30
Ashley Aitken Avatar answered Oct 21 '22 10:10

Ashley Aitken


Yes assuming you have accepted the eventual consistency of the read side. Now the question is where. Although there is no hard rule on this, it is preferable to pass the data to command handler as opposed to retrieving it inside. From my observation there are two ways:

  • Do it on domain service

Basically create a layer where you execute necessary queries to build the data. This is as straightforward as doing API calls. However if you have your microservices running on Lambda/Serverless it's probably not a great fit as we tend to avoid a situation where lambda is calling another lambda.

  • Do it on the client side

Have the client query the data then pass it to you. To prevent tampering, encrypt it. You can implement the decryption in the same place you validate and transform the DTO to a command. To me this is a better alternative as it requires fewer moving parts.

like image 1
inmyth Avatar answered Oct 21 '22 09:10

inmyth