Command Query Responsibility Segregation (CQRS)

Overview

The Event Sourcing Reference Platform implements Command Query Responsibility Segregation (CQRS) to separate the responsibilities of modifying application state from querying application data.

Rather than using a single model for both reads and writes, CQRS enables each side of the application to be independently designed, optimised and scaled.

This approach complements Event Sourcing by allowing immutable event streams to drive specialised read models tailored to the needs of the user interface.


Why CQRS?

Traditional CRUD applications typically use a single data model for both updating and querying data.

As systems become larger and more complex, this approach often results in:

CQRS addresses these issues by separating write operations from read operations.


High-Level Flow

                    User

                     │
        ┌────────────┴────────────┐
        │                         │
        ▼                         ▼
   Commands                  Queries
        │                         │
        ▼                         ▼
Command Handlers           Query Handlers
        │                         │
        ▼                         ▼
 Domain Aggregate         Azure SQL Read Model
        │                         │
        ▼                         ▼
   Domain Events          Read DTOs
        │
        ▼
 Azure Cosmos DB
    Event Store

Commands

Commands represent requests to change business state.

A command expresses intent, not implementation.

Examples include:

Commands are validated before reaching the domain model.

A successful command produces one or more domain events.

Commands do not return business data.

Typical response:


Command Processing

HTTP Request
      │
      ▼
Command DTO
      │
      ▼
Command Handler
      │
      ▼
Load Aggregate
      │
      ▼
Business Rules
      │
      ▼
Domain Events
      │
      ▼
Persist Events

The aggregate is responsible for enforcing business invariants.


Queries

Queries retrieve information without modifying application state.

Unlike commands, queries are optimised for presentation rather than business behaviour.

Queries access Azure SQL read models rather than the Event Store.

This allows:


Query Processing

HTTP Request
      │
      ▼
Query DTO
      │
      ▼
Query Handler
      │
      ▼
Azure SQL
      │
      ▼
Response DTO

Queries never execute business logic or create domain events.


Read Models

Read models are denormalised views of business data created specifically for querying.

Rather than reconstructing aggregates from events for every request, projection workers continuously update read models.

Benefits include:


Eventual Consistency

CQRS introduces eventual consistency between the write and read models.

The sequence is:

Command
    │
    ▼
Event Store
    │
    ▼
Service Bus
    │
    ▼
Projection Worker
    │
    ▼
Azure SQL
    │
    ▼
Query

Immediately after a command completes, the read model may briefly lag behind until projection processing finishes.

For most business applications this delay is measured in milliseconds or seconds.


Benefits

CQRS provides several architectural advantages.

Independent Optimisation

Write models prioritise business correctness.

Read models prioritise query performance.


Independent Scaling

Command processing and query processing can scale independently.

For example:


Simplified Domain Model

The write model focuses exclusively on business rules.

Presentation concerns remain isolated within read models.


Flexible Read Models

Different user interfaces often require different data.

CQRS allows multiple read models to be generated from the same event stream.

Examples include:


Trade-offs

CQRS introduces additional complexity compared to CRUD systems.

Advantages

Challenges

For enterprise systems with complex business rules, these trade-offs are frequently justified.


CQRS in this Project

This reference implementation includes:

Command Side

Read Side

The write model and read model are intentionally isolated to demonstrate a production-oriented CQRS architecture.


Future Enhancements

Future iterations will include: