Posted by Firuza Polad on July 7, 2025
Command Query Responsibility Segregation (CQRS)
CQRS is architectural pattern that separate responsibility of handling
Command(write operation) from Query (read operation). Note that, CQRS ≠ DDD : While CQRS can
be used with DDD, but they are completely different approach, DDD is not about applying
CQRS, focus on modeling teh BS domain, CQRS focuses on seperating operations. It just
depending on us to use or not. Main principles:
-
~ Speration: Command represent an action to system, changes system state
(create/update/delete), may have side effects. Query represent a request for retrieves
data, no side effects, read-only.
-
~ Commands: Usually contain necessary data to perform an action. Does not return
data,
exception confirmation or success status.
-
~ Command Handler: This class contain BS logic for handling Command, each Command
has
one handler and this handler interact with repositories (or UOF).
-
~ Query: Are used to fetch data from system and It has own model separated from
Commands. Unlike Commands it does not change state, only read-only operations included
here.
-
~ Query Handler: This class contain BS logic for fetching data from source,
return it in
a suitable format.
-
~ Models: In traditional architecture , the same model is used for both, reading
and
writing operation. In CQRS these responsibilities are separated, allowing better
performance. The Models for Command and Query are different, not reflect with each
other's structure. Model for Commands focus on modifying state, Model for Query focus on
data retrieval.
MediatR
The problem with CQRS is while it sepates operation for reading and writing, which increase
the complexity of architecture. Managing two seperate pipelines, makes system harder to
understand and especially for smaller project, and MediatR helps to solve some of issues
comes with CQRS. It is popular .NET library used to implement mediator pattern, which
decouple the sender (eg: controller) from receiver (eg: command/query handler). Act as a
mediator between request and handler, instead of directly invoke handler from Controller, we
send request to MediatR and It will route it to coreccet handler. This help to keep clean
seperation of concern, and make code easier to test.