Each application is unique and deserves a special approach. Luckily, app developers can choose from various architectural styles and patterns, or even combine them, to bring the best to their applications. We have previously told you about the essence and benefits of the microservice architecture in app development. For today, we have another topic — the Command Query Responsibility Segregation (CQRS) architectural pattern. So let’s now segregate (or split) our responsibilities: we are telling the story, you are reading and enjoying.
CQRS (Command Query Responsibility Segregation): what is it all about?
The split responsibilities are what lies at the heart of CQRS, a method originally introduced by Greg Young and Udi Dahan. CQRS took its inspiration from CQS (Command Query Separation) — another pattern created by Bertrand Meyer. A method should either change the state of an object or return a result, but never both. This was, according to Bertrand Meyer, the main idea behind CQS.
Command Query Responsibility Segregation (CQRS) is based on this philosophy as well. It is an architectural pattern that implies splitting your application into two separate data models. One of them is responsible for updates to the data (writing operations), the other for requests for data (reading operations). These updates and requests, according to the terminology inspired by the above-mentioned CQS, are also known as commands and queries.
Commands vs. queries: strictly different duties
Each operation is either a command or a query, but it cannot be a combination of both.
- A command (often also called a modifier or a mutator) makes changes to the system, but never returns the data.
- A query, on the contrary, retrieves information from the system but is unable to change the data.
Queries have return type, while commands return void. Commands and queries can never switch these jobs.
Your application’s command side (AKA write side, update side or domain side) is only focused on processing the commands, and query side (AKA read side or display side) is solely dedicated to retrieving and displaying the data.
Using the same or different databases
With CQRS, you could use the same database for your app’s command and query models. A user will send a command that will cause the write model to make changes to the database, and the read model will query the database to display the result.
However a more popular solution to use with the CQRS pattern, one that fully reflects its philosophy, is having different databases. Commands are sent to one database, the data is processed there and transferred to the other database, which gets updated accordingly. This approach lets you enhance performance, scalability and security.
The benefits of CQRS
One of the prominent advantages is that CQRS lets you scale and optimize your application’s write side and read side independently of each other. You can create the best conditions for each of them without negatively affecting the other. This enhances the performance, as well as giving you the flexibility to make more changes with time.
In addition to splitting responsibilities for software, you can also split them for humans. It could be very efficient to have different dev teams working on the application’s two sides. For instance, a more experienced team could be responsible for the command side with complex processing logic, and a less experienced one could take care of the query side without having to study all the other side’s processes.
CQRS also lets you create a rich, task-based UI highly focused on the user’s intentions.
Command Query Responsibility Segregation perfectly combines with another approach called Event Sourcing, the essence of which is storing all the system’s data in an event log.
Though Command Query Responsibility Segregation can work wonders, it still should be used with caution and only when justified, so it resolves complexity instead of adding it to the app.
CQRS moves away from the traditional CRUD approach which implies a single model for creating, reading, updating and deleting the information. Still, for many systems, CRUD is absolutely sufficient, so there is no need for CQRS.
Some cases in which Command Query Responsibility Segregation fits in well:
- applications with an imbalanced load, for example, with a large number of reads and smaller number of writes
- other cases when both models need to be fine-tuned separately
- complicated domains
- complex systems with difficult business logic
- complex data processing
- changing business needs, expected changes in the system
Many apps, many approaches! There always exists a perfect solution for every app, whether it is Command Query Responsibility Segregation (CQRS) or other. But there is one sure case when you needn’t split any responsibilities — if you fully entrust building your super app to our reliable web outsourcing team ;)