CQRS — Command Query Responsibility Segregation

2o5P...cmGf
12 Nov 2022
73


CQRS It’s a patterner proposed by Greg Young, that you can use a different model to update information than the model you use to read information.

command is an action that modifies an object's state or made a side effect in the system. Also, a command never returns a result after have been run.

query is only an action that should return data, and shouldn’t create a side effect in the system.

The origin of CQRS become from the concept proposed by Bertrand Meyer called CQS — Command Query Separation

It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer. More formally, methods should return a value only if they are referentially transparent and hence possess no side effects. (Wikipedia)


Architecture

CQRS, becomes many advantages, for example, scalability.


MVC — with command stack from the left side, and query stack from the right side


In the image above, we have a clear segregation between the command stack and the query stack, so the CQRS shows us that is possible to improve the data store (when necessary), separating on a read and write database.


MVC — with command stack from the left side, and query stack from the right side, now with a read and write database


Hands-on

In this hands-on, I’ll show you how you could implement the CQRS pattern. I’m using the onion architecture, but it is not a problem if you don’t know about this, the focus is only on the CQRS pattern, if you were curious about Onion Architecture after you finish this story, check out my post about it.

The Practical Onion Architecture — the onion that doesn’t make you cry

Command flow


POST method in charge of to run a command that stores purchase orders


We can see that the PurchaseOrderController in your method createPurchaseOrder receives a command, I’m called the DTO as PurchaseOrderRequest

DTO — PurchaseOrderRequest


After the controller process the request, and run the business logic, and application logic, the PurchaseOrderEntityProvider saves the order directly in the write database

Command running and saving the order directly in the write database


Query Flow

The query in this case is only GET in the PurchaseOrderController, listing all purchase orders.

GET method in charge of to run a query that retrieves a purchase orders list


Sometimes the input model will be the same properties output model, but they have different objectives.

the PurchaseOrderResponse is in charge to represent the view data.


After to sent to the data-provider layer, the PurchaseOrderProviderImpl runs this query directly in the read database.

To run directly in the read database as I’m using Springboot was need to configure this, so is necessary to have the two connections (WRITE database and READ database)

And when I put the annotation @Transactional with the parameter (readOnly = true) this transaction will be in the read database.

Query running and getting orders directly in the read database



A little more about CQRS

So, CQRS doesn’t only have a read database and write database but has a separation between what is a command and a query.
Also, we could use a cache for example.
Remember when to use the CQRS to have a replication mechanism.


References

Greg Young — CQRS and Event Sourcing — Code on the Beach 2014
CQRS Documents by Greg Young
Rodrigo Branas — CQRS with Greg Young
Elemar Jr — Descomplicando CQRS (PT-BR)


Get fast shipping, movies & more with Amazon Prime

Start free trial

Enjoy this blog? Subscribe to andrelucas

8 Comments