How To Understand CQRS In Microservices Architecture

Oleksii Dushenin
3 min readNov 22, 2021

In a previous post, How To Implement Asynchronous Interactions Between Microservices, a general idea behind microservices communications via message brokers was discussed. In this article, a specific pattern of microservices architecture, CQRS ( Command Query Responsibility Segregation), will be reviewed.

Problem Statement

In typical software applications, there is a data store that is responsible for write and read operations. Usually, the application implements some CRUD operations and it is very simple. You store something and read the same result.

However, in complex applications situation is not so trivial. Each read and write operation can require a lot of actions and constraints.

For instance:

  • Write: A database is structured in a normalized way to eliminate data duplications and enforce constrains. Read: Complex read queries require a lot of joins/unions/aggregations that negatively affects performance.
  • Read: Indexes are required to optimize queries. Write: Indexes are updated in each write operation.
  • Read/Write representations can be different, which can be a cause of the additional logic.
  • Data contention can occur during parallel operations on the same data.
  • Performance can be poor because of the load on the database.

CQRS

The solution to the described problem is CQRS ( Command Query Responsibility Segregation).

Let’s review the picture above. It contains two services: Hotel Management Service and Hotel Read Service (actually, there can be multiple different Read services with their own databases, if they are required). Data should be in sync between these services. For this purpose, some message broker is typically used (e.g. Kafka). The data formats are different in these services.

Hotel Management Service is responsible for create/update/delete operations, each of which is described as a command:

  • Make/Approve/Decline a hotel creation request.
  • Add/Update hotel room to the system.
  • Change price of the hotel room.
  • Book hotel room for specific time period.
  • Request additional services.
  • Make a request to leave/approve/reject a comment.
  • Cancel booking.

Hotel Read Service is only responsible for showing the list of hotels/rooms to the user:

  • List all/available hotel rooms in a city.
  • Show all hotels on the map (filtering by geolocations).
  • Show available filter options to the user.
  • Filter hotel rooms by specified filters (e.g. show two hotel rooms instead of one for many people).

As you can see, the responsibility of provided services is different. Also, performance constraints are different for specified services. Users usually go through many booking options before making a booking. As a result, in this system, the number of read operations is much higher than the number of write operations. Therefore, scaling will be different for these services.

As a result, some RDBMS can be used e.g. MySQL or PosgreSQL as a data storage for Hotel Management Service. It will bring all benefits of RDBMS to keep data safe.

Hotel Read Service can be based on some NoSQL solution like MongoDB or Elasticsearch. The reason behind that is the ability to perform efficient search queries: denormalization, geolocation search support, indexing, horizontal scaling, etc.

CQRS Advantages

  • Separation of concerns.
  • Individual read and write services scaling.
  • Suitable data storage and its schema for both read and write operations.
  • Simple and efficient queries.

CQRS Disadvantages

  • Complexity.
  • Eventual consistency.

Summary

In this post, the CQRS pattern was reviewed. It is worth mentioning, that the necessity in this pattern can occur in complex systems. As a result, it should be chosen carefully in order not to bring unnecessary complexity to your system.

Originally published at https://datamify.com on November 22, 2021.

--

--