Problem of Bloated Domain objects
In business software applications, the domain objects (entities) are used to represent the business domain. As the application grows and adds more business logic, the service layer, mappers and other patterns gets applied. Often this leads to domain object becomes bloated and the related components become huge & un-maintainable.
CQRS solves the common problem of having a bloated Domain objects. The domain objects get bloated largely because of bounded context. The series of contexts which makes developers think that a single domain object is sufficient to handle all the related things. For example, a large Invoice object for handling Invoice, Shipment and handling change of address for customer . But in reality, these contexts (invoicing, shipment and change) need not be related to same Invoice entity.
What is Command, Query Responsibility segregation (CQRS)?
In order to simplify the Domain objects, CQRS proposes to have two types of domain entities.
- those serving the command (ordering/assertion services) – For example, SaveCustomer, CreateInvoice, ShipProduct etc
- those serving a Query (request) – examples include GetCustomerAddress, SearchCustomer etc
With this separation, the complexity (number of fields, methods) of entities used becomes simplified. And hence the Data mapper layers & the service layers becomes more simplified.
Where can I use CQRS?
- Largely complex system: Applying CQRS on a simple CRUD operation based system is a over kill. When there is a domain heavy system, like banking and financing systems, LOB applications where business logic, lots of boundary conditions are heavy. Where it makes DDD (Domain driven design) provides high value.
- Situations where you will apply Microservices, Eventual consistency and Event Sourcing. When we have separation of concerns using CQRS, the microservices becomes much simpler to design and maintain. With Event sourcing we are focused on getting the data (query) from other related sources and is what CQRS propagates.
CQRS is a carefully thought out pattern for simplifying & solving large and complex systems.
Microservices is a really becoming a famous architectural pattern that most of the new software written these days, just apply them. One of the most important differentiation between the traditional web services and micro-services pattern is the amount of common stuff across different subject areas. This calls for a discussion on how Eventual Consistency pattern is mandatory for successfully implementing microservices.
The micro frontend if gaining lots of popularity. You can read about microservices principles and micro frontends at
Microservices and Microfrontends
Generally, in a micro-service pattern, the API’s are split into small subject areas. For example for a CRM application, the subject areas are
- Customer information – like name, address, email, phone
- Appointment information – which customer, salesperson, when, where
- Relationship management – sales/manager, what products, interests
- Campaign data – offers, deals etc
Then micro-services are built for each of the subject areas. The microservices are logically and physically separated from each other. ie there is no sharing (code, database, component etc) between any of these micro-services of these subject areas. Pictorially its looks something like this.
Applying Eventual Consistency Pattern
In Micro-services, there is no data that is shared across the micro services. In order to synchronize the data across these isolated storages of these services, we need to apply the eventual consistency pattern. You can read more about applying the pattern correctly here. The simpler way we can achieve consistency across these micro-services is through Event Sourcing pattern.
Event sourcing is a process of capturing application state changes in the form of events. An example of events are customer created, customer updated, Deal created, etc. Other systems listen to these events and they take relevant action. You can read more about event sourcing here.
Event sourcing is the new way of storing changes to systems and help in making micro-services eventually consistent. These patterns together form well maintainable, reliable and scalable systems in the modern world.