Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CQRS Overview

Command Query Responsibility Segregation (CQRS) separates the write model (how you change data) from the read model (how you query data). Event sourcing and CQRS complement each other naturally.

The Split

Write Side (Commands)Read Side (Queries)CommandAggregateEventsStoreEvent StoreProjectionViewQuery  Event StoreEvent StoreEvent StoreRead ModelRead Model  







Write side: Commands validate against the aggregate and produce events. The aggregate enforces business rules.

Read side: Projections consume events and build optimized views for queries. Each projection can structure data however the UI needs.

Why Separate?

ConcernWrite ModelRead Model
Optimized forConsistency, validationQuery performance
StructureReflects domain behaviorReflects UI needs
UpdatesTransactionalEventually consistent
ScalingConsistent writesReplicated reads

A single aggregate might feed multiple projections:

EventsAccount SummaryTransaction HistoryFraud DetectionAnalytics Dashboard  



Each projection sees the same events but builds a different view.

In This Crate

The crate models CQRS through:

  • Aggregate + Handle<C> — the write side
  • Projection + ApplyProjection<E> — the read side
  • Repository — orchestrates both
// Write: execute a command
repository
    .execute_command::<Account, Deposit>(&id, &command, &metadata)
    .await?;

// Read: build a projection
let summary = repository
    .build_projection::<AccountSummary>()
    .event::<FundsDeposited>()
    .event::<FundsWithdrawn>()
    .load()
    .await?;

Eventual Consistency

With CQRS, read models may not immediately reflect the latest write. This is fine for most UIs—users expect slight delays. For operations requiring strong consistency, read from the aggregate itself (via aggregate_builder).

Next

Architecture — How the components fit together