Recent Posts
Archives

Posts Tagged ‘CQRS’

PostHeaderIcon [DevoxxBE2013] CQRS for Great Good

Oliver Wolf, principal consultant and executive board member at INNOQ, challenges conventional architectures with CQRS (Command-Query Responsibility Segregation). A SOA and Java expert, Oliver traces CQRS’s evolution from CQS, demonstrating incremental adoption—from read-write separation to event sourcing. His session, enriched with examples, equips developers to rethink data flows, optimizing for asymmetric workloads in banking and beyond.

CQRS decouples commands (writes) from queries (reads), enabling tailored models. Oliver illustrates phased implementation, culminating in event-sourced systems for auditability and scalability.

From CQS to CQRS: Foundational Concepts

Oliver recalls CQS—Bertrand Meyer’s principle segregating mutators from inspectors. CQRS extends this, allowing distinct read/write models. He demos a simple e-commerce app, splitting a unified model into command (order placement) and query (inventory views).

This separation, Oliver explains, resolves impedance mismatches, enhancing performance.

Incremental Adoption Strategies

Phased rollout minimizes risk: start with asymmetric databases, Oliver advises, using separate stores for reads/writes. He showcases materialized views, syncing via background jobs.

Advanced steps introduce event sourcing: commands emit events, replayed for state reconstruction, ensuring immutability.

Event Sourcing and Distribution

Event sourcing captures changes as immutable logs, Oliver illustrates, rebuilding state on demand. Distribution follows: client/server variants, with web frontends querying dedicated services.

In banking, Oliver notes, CQRS optimizes configurable systems, balancing risk with extensibility.

Guidelines for Application

Oliver urges starting small: identify read-heavy operations, segregate gradually. Avoid over-engineering; CQRS suits complex domains, not simple CRUD.

Community examples, he shares, validate phased approaches, with INNOQ projects exploring hybrid models.

Links:

PostHeaderIcon [DevoxxFR2013] Distributed DDD, CQRS, and Event Sourcing – Part 1/3: Time as a Business Core

Lecturer

Jérémie Chassaing is an architect at Siriona, focusing on scalable systems for hotel channel management. Author of thinkbeforecoding.com, a blog on Domain-Driven Design, CQRS, and Event Sourcing, he founded Hypnotizer (1999) for interactive video and BBCG (2004) for P2P photo sharing. His work emphasizes time-centric modeling in complex domains.

Abstract

Jérémie Chassaing posits time as central to business logic, advocating Event Sourcing to capture temporal dynamics in Domain-Driven Design. He integrates Distributed DDD, CQRS, and Event Sourcing to tackle scalability, concurrency, and complexity. Through examples like order management, Chassaing analyzes event streams over relational models, demonstrating eventual consistency and projection patterns. The first part establishes foundational shifts from CRUD to event-driven architectures, setting the stage for distributed implementations.

Time’s Primacy in Business Domains

Chassaing asserts time underpins business: reacting to events, analyzing history, forecasting futures. Traditional CRUD ignores temporality, leading to lost context. Event Sourcing records immutable facts—e.g., OrderPlaced, ItemAdded—enabling full reconstruction.

This contrasts relational databases’ mutable state, where updates erase history. Events form audit logs, facilitating debugging and compliance.

Domain-Driven Design Foundations: Aggregates and Bounded Contexts

DDD models domains via aggregates—consistent units like Order with line items. Bounded contexts delimit scopes, preventing model pollution.

Distributed DDD extends this to microservices, each owning a context. CQRS separates commands (writes) from queries (reads), enabling independent scaling.

CQRS Mechanics: Commands, Events, and Projections

Commands mutate state, emitting events. Handlers project events to read models:

case class OrderPlaced(orderId: UUID, customer: String)
case class ItemAdded(orderId: UUID, item: String, qty: Int)

// Command handler
def handle(command: AddItem): Unit = {
  // Validate
  emit(ItemAdded(command.orderId, command.item, command.qty))
}

// Projection
def project(event: ItemAdded): Unit = {
  updateReadModel(event)
}

Projections denormalize for query efficiency, accepting eventual consistency.

Event Sourcing Advantages: Auditability and Scalability

Events form immutable logs, replayable for state recovery or new projections. This decouples reads/writes, allowing specialized stores—SQL for reporting, NoSQL for search.

Chassaing addresses concurrency via optimistic locking on aggregate versions. Distributed events use pub/sub (Kafka) for loose coupling.

Challenges and Patterns: Idempotency and Saga Management

Duplicates require idempotent handlers—e.g., check event IDs. Sagas coordinate cross-aggregate workflows, reacting to events and issuing commands.

Chassaing warns of “lasagna architectures”—layered complexity—and advocates event-driven simplicity over tiered monoliths.

Implications for Resilient Systems: Embracing Eventual Consistency

Event Sourcing yields antifragile designs: failures replay from logs. Distributed CQRS scales horizontally, handling “winter is coming” loads.

Chassaing urges rethinking time in models, shifting from mutable entities to immutable facts.

Links: