Zum Hauptinhalt springen

CQRS (Command Query Responsibility Segregation)

Einleitung

CQRS trennt Befehle (Commands) von Abfragen (Queries).

Die Grundidee:

Schreiben und Lesen haben unterschiedliche Anforderungen –
also sollten sie nicht zwangsläufig dasselbe Modell teilen.

CQRS ist kein Default-Pattern.
Es ist ein gezieltes Instrument für komplexe Domänen oder asymmetrische Lastprofile.


Einordnung

CQRS ist ein Applikations- und Modellierungs-Pattern.

Wichtig:

  • Es ist unabhängig von Microservices.
  • Es funktioniert im Monolithen genauso.
  • Es erzwingt keine getrennten Deployments.

CQRS trennt Modelle, nicht zwingend Systeme.


Grundprinzip

Kernaussage:

  • Writes gehen durch ein konsistenzfokussiertes Modell.
  • Reads nutzen eine optimierte Sicht.
  • Synchronisation erfolgt häufig über Events.

Zielsetzung

CQRS adressiert:

  • Unterschiedliche Performance-Anforderungen
  • Komplexe Geschäftsregeln beim Schreiben
  • Sehr hohe Lese-Last
  • Unterschiedliche Sicherheitsanforderungen

Nicht:

  • „Weil Microservices modern sind“

Charakteristika

1️⃣ Write Model

  • Validiert Geschäftsregeln
  • Erzwingt Invarianten
  • Arbeitet transaktional
  • Modelliert Verhalten (Behavior over Data)

2️⃣ Read Model

  • Optimiert für Abfragen
  • Oft denormalisiert
  • Kann mehrere Views enthalten
  • Darf Redundanz enthalten

3️⃣ Synchronisation

  • Häufig über Domain Events
  • Oft eventual consistency
  • Kann auch synchron erfolgen (einfachere Variante)

CQRS zwingt nicht zu Eventual Consistency – aber viele reale Implementierungen führen dazu.


Varianten von CQRS

🟢 Light CQRS

  • Getrennte Klassen/Layer für Commands und Queries
  • Gemeinsame Datenbank
  • Keine Event-Projection

→ Geringe Komplexität


🟡 Full CQRS

  • Getrennte Modelle
  • Separate Read/Write Stores
  • Event-getriebene Projektionen

→ Höhere Komplexität, höhere Flexibilität


🔴 CQRS + Event Sourcing

  • Write-Model speichert Events statt State
  • Read-Model wird aus Event-Stream aufgebaut

→ Sehr mächtig, sehr komplex


Vorteile

  • Optimierte Leseperformance
  • Saubere Domänenmodellierung
  • Skalierbarkeit der Read-Seite
  • Klare Verantwortlichkeiten im Code

Risiken / typische Fallstricke

1️⃣ Überengineering

CRUD-Systeme brauchen meist kein CQRS.


2️⃣ Eventual Consistency

Benutzer müssen verstehen:

  • Daten sind nicht sofort überall konsistent.

3️⃣ Doppelte Modelle

Zwei Modelle bedeuten:

  • Mehr Code
  • Mehr Tests
  • Mehr Wartung

4️⃣ Falsche Motivation

„Wir haben Microservices, also brauchen wir CQRS.“

Das ist kein valider Grund.


Wann sinnvoll?

  • Komplexe Geschäftslogik beim Schreiben
  • Hoher Read-Load
  • Unterschiedliche Sicherheitsanforderungen
  • Reporting-/Query-Optimierung notwendig

Wann unnötig?

  • CRUD-dominiert
  • Kleine Anwendungen
  • Einheitliche Lastprofile
  • Team unerfahren mit verteilten Modellen

Strategische Perspektive

CQRS ist ein Komplexitätsmultiplikator mit hohem Nutzenfaktor.

Wenn die Domäne komplex ist, reduziert CQRS langfristig Komplexität.

Wenn sie einfach ist, erhöht CQRS unnötig Komplexität.


Fazit

CQRS trennt Verhalten von Abfragen.

Es ist sinnvoll bei:

  • komplexer Domäne
  • asymmetrischer Last
  • Skalierungsbedarf auf der Read-Seite

Es ist nicht:

  • automatisch moderner
  • automatisch skalierbarer
  • automatisch besser

Es ist ein gezieltes Werkzeug – kein Architektur-Statement.