What is CQRS
What is CQRS?
CQRS is a design pattern that has been heavily adopted in the DDD space of design and building software. Command Query Responsibility Segregation. In it’s simplest form it is the idea of separating Commands from Queries, in other words, a method should only return a result, or change the state of an object, but it should never do both. Separating the reads from the writes is where the real strength of CQRS come from, because the write side is known as the domain, this should contain all the behavior for that particular domain, you don't want the read side manipulating any of it and this helps the read side focus on just one thing, which is retrieving the data in however many forms is needed and for reporting.
Queries are the read side of the application and should only contain methods that return your data. These would be the DTO’s that you are using internally or to display to your users on the frontend. DTO’s are usually a representation of what the actual data looks like in your datastore. This operation is read-only, meaning we can run this operation as my times as we like, it will always return the same data until we do an operation on that entity, which we will use a Command for.
Commands are the write side of you application. This is the part of your application that responsible for introducing all changes to your system. Commands are like messages that you send to your domain objects to perform specific tasks to manipulate the data (UpdateOrderStatus, AddProduct, etc.). Commands should not return anything.
Commands usually perform the following tasks:
- Validates the command is a valid command
- Manipulate the data as commanded by the system (UpdateProdctLeadTime, UpdateProductDescription)
- Persist the new state to the datastore
In the event that a command is invoked on your system, the querying side needs to be notified of this so that it has the latest state of you data. At this stage, what you want to do is execute an event that notifies your system of this change that can be consumed by one or more consumers. This is also known as eventual consistency (More on this in a future blog post).
An event is a system notification that something has changed. You normally want to adhere by a naming convention of naming your events in the past tense because this will only happen once your commands have successfully executed. These events are then consumed by one or many subscribers and are in charge of keeping your datastores synchronized for when they are queried by the querying side.
It can be easy to confuse a command with an event, or vice versa, but to make it a bit more digestible, think of a command as something that must happen, and an event as something that has happened.
When to use CQRS
There a few use cases for implementing the CQRS pattern into your application, but I feel like it will benefit you most if you have a large, multi-user, ever-changing-data application. The separation of the queries and writes will allow you to scale them independently and most important, personally, you will have more flexibility when optimizing the read side, chances are this will happen more frequently than the write side, because let’s face it, reading data from you system will happen a lot more than changing it. One con I would throw in here is that this pattern does add a degree of complexity, so really think about it before re-writing your entire application.
See this article if you want learn more of the risks involved in implementing this pattern.
In my next blog post I will expand on this topic and introduce a couple of topics known as Event sourcing and Eventual consistency, which only helps and improves the CQRS pattern.