In this article as an introductory part of CQRS Pattern Series, the topics are explained independently of the software language. In addition, explained CQS Pattern, Event Sourcing Pattern, and Axon Framework.
I planned to create this series in 3 parts. The next article will be about the implementation of the CQRS Pattern using Microservice Architecture and Axon Framework. And the other one will be implementing of Saga Pattern.
In the following, some of these topics are a lot of significant subjects that I summarized. I prefer to focus on CQRS Pattern and develop an application example.
The extended version of CQRS is the Command Query Responsibility Segregation. It is especially used in projects with Microservice Architecture. The primary purpose of CQRS is; as can be understood from the extended version, it is to separate the responsibilities of the write and read operations.
After the front introduction of CQRS, I want to touch on CQS Pattern because CQRS can be considered an improved version of the CQS (Command Query Separation) Pattern.
Bertrand Meyer designed CQS Pattern in 1980 as part of his work on the Eiffel programming language. It says that operations that will make changes to data should be separated from operations that will only perform read operations without making any changes to the data.
Let us continue talking about CQRS. What are write and read operations mean? Actually, we can analyze it under two main headings.
The commands change the state of objects by performing operations such as insert, update, and delete. It does not return any information.
We can think of it as the select operation that returns the specified data model. It does not change the state of objects.
As seen in the picture above, write and read operations are separated. This situation allows these operations/services can work same time and can be scaled separately. Let us think, of a project that has more read requests than write that is created with CQRS Pattern. We can scale just read services, this way avoid to scale the writing service unnecessarily. To summarize the advantages of CQRS:
- Choosing an independent database; is possible when using separate databases for writing and reading services,
- Efficient and independent scaling,
- Better performance,
What I wrote above as an advantage may have some side effects. Each separation shows up extra cost and consistency needed. You can look at the big picture to find out the consistency part, CAP Theorem. If you want to implement CQRS on your projects, consider all side effects as well, like each pattern or architecture.
- In a possible crash, only successful transaction management (Saga and Outbox Patterns) saves from this situation,
- Databases should be synced regularly; this is possible with the Eventual Consistency item of the BASE Model,
- Complexity; if we want to add new features, it could be difficult,
- More costs.
When should CQRS be implemented?
CQRS is more useful in some places than others. For example, others could be simple or stable projects or have equal requests to write and read operations and projects. Now, let us focus on useful places.
Contrary to the above, CQRS could be useful for systems in that the count of write and read operations differ greatly. If some projects have the following items, that should be implemented CQRS pattern.
Event Sourcing Pattern
CQRS fits well with Event-Based Architecture. As I mentioned above, distributed systems need to provide consistency with Eventual Consistency to sync separate storage. Event Sourcing Pattern is a reliable solution for this situation that stores events and provides using these saved events when needed. Let’s focus on the event.
An Event is a track of changes in data due to requests. The naming convention should be written with the past tense suffix like ProductUpdatedEvent because the changes are complete.
Back to the main topic, the stored event is always retained in this pattern. Instead, a new event is saved in the event store. The main purpose of Event Sourcing is that saves all changes flow on data, not just the result. Since all events are held that allows a return to the moment T when events were stored.
As explained above, events are related to changes in data. Systems have a lot of data and need to separate these from each other. The following topic is related to this requirement.
Each change on the storage must be synced with the other. Because of this need, projections can be used. Projections can be implemented in different ways and used in both read models and write models. Also, it is a way to create state information using the event stream.
An aggregate is used to distinguish all events related to data from the other data events and it is all of the events that belong to a data. This also gives us transaction integrity.
Axon is a microservice systems-based, and open-source framework. Domain-Driven Design (DDD), Command-Query Responsibility Separation (CQRS), Event Sourcing, Saga Pattern, and more can be implemented using Axon.
It saves us from code complexity and provides an interface to examine our system. High disk and memory usage are the some of downsides. If you want to learn more information about Axon you can visit this website.
In future articles, we will start to create an application. It will be a project that included several microservices with CQRS Pattern and setting up Axon Framework in Docker.
Nevertheless, if you have any questions which are related to these topics, please do not hesitate to contact me via LinkedIn.
Thanks for reading the end of the article. See you in the next articles.
CQRS stands for Command Query Responsibility Segregation. It's a pattern that I first heard described by Greg Young. At…
Microservices Pattern: Event sourcing
A service command typically needs to update the database and send messages/events. For example, a service that…