Eliminierung technischer Schulden mit PHPStan, Rector PHP und PHPUnit. Über 20 Jahre Praxiserfahrung in skalierbaren Backends.
- Aktualisiert:
- Autor:
- Roland Golla
CQRS: Definition und Einordnung
Inhalt
CQRS mit NCA: Schnelle Hilfe vom Experten
Gesetzliche Konformität & Inklusion. Optimierung von Performance und Conversion durch radikal nutzerzentriertes, universelles Design.
Skalierbare KI-Systeme mit echtem Code Ownership. CI/CD, Backup-Strategien und Infrastruktur, die mit deinem Team wächst.
Command und Query im Alltag unterscheiden
- Command: CancelOrder, IncreaseDunningLevel, RecordPayment. Formuliert als Absicht, nicht als Datensatz.
- Query: OpenOrdersOfCustomer, RevenueOverview. Liefert genau die Form, die die Oberfläche braucht.
- Handler: Jede Absicht und jede Abfrage bekommt eine eigene kleine Klasse statt einer Service Klasse mit zwanzig Methoden.
CQRS in PHP mit Symfony Messenger
final readonly class CancelOrder
{
public function __construct(
public OrderId $orderId,
public string $reason,
) {
}
}
#[AsMessageHandler(bus: 'command.bus')]
final readonly class CancelOrderHandler
{
public function __construct(
private Orders $orders,
) {
}
public function __invoke(CancelOrder $command): void
{
$order = $this->orders->withId($command->orderId);
$order->cancel(new CancellationReason($command->reason));
$this->orders->save($order);
}
}
final readonly class OpenOrdersHandler
{
public function __construct(
private Connection $connection,
) {
}
public function __invoke(OpenOrders $query): array
{
return $this->connection->fetchAllAssociative(
'SELECT number, customer, total_cents FROM orders WHERE status = :status',
['status' => 'open'],
);
}
}
framework:
messenger:
default_bus: command.bus
buses:
command.bus: ~
query.bus:
middleware:
- validation
CQRS in Stufen statt als Alles oder Nichts
| Stufe | Was getrennt wird | Preis dafür |
|---|---|---|
| Stufe 1 | Methoden: Commands ändern, Queries lesen | Fast keiner, reine Disziplin im Code |
| Stufe 2 | Eigene Handler je Absicht und Abfrage | Mehr Klassen, dafür kleine und testbare Einheiten |
| Stufe 3 | Eigene Lesemodelle neben dem Domänenmodell | Zwei Modelle müssen gepflegt werden |
| Stufe 4 | Eigener Lesespeicher, asynchron aktualisiert | Eventual Consistency und deutlich mehr Betrieb |
Wann CQRS trägt und wann es nur kostet
CQRS is not an architecture.
Die NCA Erfahrung mit getrennten Modellen
Erreichen Sie unsere PHP Consultant Spezialisten
Wir sind Experten für PHP und helfen Ihnen, Ihre digitalen Herausforderungen zu meistern. Unser erfahrenes Team unterstützt Sie bei PHP Updates, PHP Refactoring und berät Sie remote zu allen Fragen rund um PHP. Mit unseren vollautomatischen CI/CD Deployments und einer robusten Docker-Infrastruktur bringen wir Ihre PHP-Projekte auf das nächste Level. Vertrauen Sie auf unsere Expertise für zuverlässige und skalierbare PHP-Lösungen.
Häufige Fragen zu CQRS
Was ist CQRS 2026 einfach erklärt?
CQRS steht für Command Query Responsibility Segregation und trennt schreibende von lesenden Zugriffen. Ein Command beschreibt eine Absicht, ändert Zustand und gibt nichts zurück. Eine Query liefert Daten und ändert nichts. Dadurch darf die Schreibseite fachlich streng sein, während die Leseseite genau die Form liefert, die die Oberfläche braucht.
Braucht CQRS 2026 zwingend Event Sourcing?
Nein. Beides wird oft gemeinsam genannt, funktioniert aber unabhängig voneinander. CQRS lässt sich mit einer einzigen relationalen Datenbank umsetzen, indem Lesezugriffe direkt per SQL laufen und Schreibzugriffe über das Domänenmodell. Wer beides gleichzeitig einführt, verdoppelt das Risiko ohne Notwendigkeit.
Wie setzt man CQRS 2026 in Symfony um?
Über den Messenger mit zwei getrennten Bussen. Commands laufen über den Command Bus zu einem Handler je Absicht, Queries über den Query Bus zu einem Handler je Abfrage. Die Konfiguration ist kurz, der eigentliche Gewinn liegt in kleinen Klassen mit klarem Zweck statt einer Service Klasse mit zwanzig Methoden.
Lohnt sich CQRS 2026 für kleine Projekte?
Nur in der einfachsten Stufe. Die Trennung von ändernden und lesenden Methoden kostet nichts und verbessert jeden Code. Eigene Lesemodelle oder gar ein eigener Lesespeicher lohnen sich erst, wenn Schreibregeln komplex sind oder die Leselast deutlich abweicht. Für eine Verwaltungsanwendung ist das Overkill.
Welche Rolle spielt CQRS 2026 bei KI gestützter Entwicklung?
Kleine Handler mit klarem Zweck sind für einen Agenten deutlich leichter zu ändern als eine gewachsene Service Klasse. Jede Absicht hat eine eigene Datei, einen eigenen Test und einen eindeutigen Namen. Damit bleibt der Ausschnitt klein, den ein Modell verstehen und zuverlässig anfassen kann.
Was ist der Unterschied zwischen CQS und CQRS?
CQS ist das ältere Prinzip auf Methodenebene: Eine Methode ändert entweder etwas oder liefert etwas zurück, nie beides. CQRS überträgt diesen Gedanken auf die Ebene der Modelle und erlaubt getrennte Modelle für Schreiben und Lesen. CQS gilt überall, CQRS ist eine bewusste Entscheidung pro Bereich.
Was bedeutet Eventual Consistency in diesem Zusammenhang?
Wird die Leseseite asynchron aktualisiert, sieht ein Nutzer seine Änderung eventuell erst Sekundenbruchteile später. Fachlich muss das in Ordnung sein. Bei einer Statistik ist es unkritisch, bei einer Buchung mit sofortiger Bestätigung nicht. Diese Frage gehört vor die technische Entscheidung, nicht danach.
Wo liegt der häufigste Fehler bei CQRS?
Die flächendeckende Einführung im gesamten System. CQRS ist eine Entscheidung pro Bounded Context und oft nur für einzelne Bereiche sinnvoll. Zweiter häufiger Fehler sind Commands, die wie Datenbankoperationen heißen. Heißt ein Command update, ist die fachliche Absicht bereits verloren gegangen.
Dürfen Queries direkt auf die Datenbank zugreifen?
Ja, das ist sogar ein Kernpunkt. Die Leseseite braucht das Domänenmodell nicht und darf mit einfachem SQL genau die Spalten holen, die angezeigt werden. Wichtig ist nur, dass sie nichts ändert und dass dieser Zugriff technisch abgesichert bleibt, etwa über Deptrac Regeln.
Wie testet man Commands und Queries?
Commands über die Fachregeln: Ein Handler bekommt ein Command, danach wird geprüft, ob das Aggregate den erwarteten Zustand hat. Queries über das Ergebnis: Testdaten anlegen, Abfrage ausführen, Struktur prüfen. Beides läuft mit PHPUnit, für das Zusammenspiel im Container hilft Symfony KernelTestCase.
Lässt sich CQRS nachträglich einführen?
Ja, schrittweise und pro Anwendungsfall. Üblich ist der Start bei einer langsamen Übersicht, die eine eigene Abfrage bekommt. Danach folgen weitere Bereiche. Vorher sollte das aktuelle Verhalten mit Tests festgehalten werden, damit die Umstellung vergleichbar bleibt.
Wie unterstützt NCA bei der Einführung?
Wir messen zuerst, wo das Problem wirklich liegt, und prüfen, ob eine einfachere Lösung reicht. Ist CQRS der richtige Weg, bauen wir es abgesichert mit Tests und Parallel Run um. Jede Zusammenarbeit beginnt mit einem kostenlosen Kennenlernen, danach schätzen wir den Aufwand ein und rechnen transparent minutengenau ab.