Es gibt eine Menge Meinungen bezüglich CQRS mit DDD und was jede Komponente ausmacht. Ich habe noch nicht damit begonnen, sich mit Event Sourcing zu beschäftigen, daher enthält die folgende Liste nichts, was damit zu tun hat. Obwohl Einblicke in ES wäre interessant.CQRS-Komponentenrollen und -Verantwortlichkeiten mit einer REST-API
Bis jetzt habe ich die folgenden Komponenten mit den damit verbundenen Verantwortlichkeiten (siehe unten). Ich habe einige Fragen in den folgenden Punkten angesprochen.
REST-Endpunkte/Anwendung
- Anfrage Empfangen von Benutzer/ui/etc
- Baukonstruktion und dem Versand relevanter Befehl
- Wenn die Sollwerte von anderen begrenzten Kontexten erfordern, führen Sie dann die entsprechenden Finder Aufrufe erforderlich, um den Befehl korrekt zu instanziieren (z. B. Auftrag erfordert Benutzer-ID)
- Im Falle eines GET: der entsprechende Finder heißt
- Finder sitzen auf dieser Ebene der Anwendung. Die schreibgeschützte Seite von Bounded Contexts (Befehlshandler, Aggregat, Factory, Domänenservice usw.) sollte Finder nicht aufrufen. Dadurch wird die Einkapselung aufrechterhalten, und indem nur die erforderlichen Daten (anstelle der vollständigen DTOs) in die Befehle eingegeben werden, wird es zu einer bescheidenen Anti-Korruptionsschicht.
- Zum Beispiel:
AggregateId orderId = AggregateId.get(); AggregateId userId = finder.findUserAggregateIdByEmail (E-Mail); dispatcher.fire (neuer CreateOrderCommand (orderId, userId, orderItems));
Befehl
- Änderungen an der Domain durch den Versand Befehle gemacht werden
- Befehle sind unveränderlich und enthalten die notwendigen Daten für eine Bounded Context zu verändern, es Zustand ist oder werfen eine Ausnahme
- Der Befehl Die Eingabe kann bei der Objekterzeugung überprüft werden, um zu vermeiden, dass ungültige Befehle gesendet werden.
- Zum Beispiel:
new CreateOrderCommand(orderId, userId, orderItems);
Befehl Handler
- Der Handler kann entweder den Befehl erfolgreich anwenden oder eine Ausnahme
- Es erheben kann nur ein Befehlshandler für jeden Befehl seines
- Der Handler wird die Aggregate laden oder erstellen Root (Repository oder Aggregate Factory)
- Der Handler wird den Befehl auf den Aggregatstamm anwenden
- Der Handler-Deal s mit dem Repository
- Keine Befehle auslösen (innerhalb oder außerhalb des beschränkten Kontexts)
- Sollte der Befehls-Handler Ereignisse versenden? Zum Beispiel nach dem erfolgreichen Speichern in der Datenbank? Oder ist das allein die Verantwortung des Aggregates?
Aggregate Fabrik
- Fasst die Logik erforderlich, um ein Aggregat Wurzel richtig
- Die Fabrik zur Initialisierung kann auf das Repository zugreifen
- Sollten die Fabrik Zugang Domain Services?
- Zum Beispiel:
factory.createOrder(orderId, userId, orderItems);
Aggregate Root/Aggregate
- Enthält die Domänenlogik, Zustand und Verhalten
- Verantwortlich für den Versand Events
- Aggregate Root-Zugriff auf Aggregate kapselt
- Aggregat Root sollte eine ID haben, die eindeutig i
order.cancel();
Domain-Service
- Dies beinhaltet, was passt nicht ganz in: dentifies es
- Sollte nicht mit externen Diensten (ausgenommen Ereignisse Verlag)
- Zum Beispiel interagieren ein Aggregatstamm
- Mit welchen Komponenten kann der Domänenservice interagieren?
- Sollte der Domain-Service Befehle/Ereignisse auslösen?
- Zum Beispiel: Nicht sicher, was hier zu verwenden ist, der erste Punkt oben ist vage bestenfalls vage. Das meiste Verhalten liegt gut im Aggregat oder kann durch Sagas/Events/Commands erreicht werden. Was wäre ein gültiges Beispiel hier?
Repository
- Kümmert Laden/Speichern/Aktualisieren/etc unsere Aggregate
- Zum Beispiel:
repo.load(orderId);
Ereignis
- Stellt etwas, das in einem Aggregat hat (oder Befehls-Handler, etc., wenn sie auch Ereignisse feuern)
- Events unveränderlich sind
- Andere Kontexte im System begrenzt ein Ereignis verwenden können Entscheidungen
- Zum Beispiel zu machen :
new OrderCancelledEvent(orderId);
Event Handler
- Reagiert auf ein Ereignis tha t fand
- Es können mehrere Event-Handler für ein einzelnes Ereignis in der gleichen oder unterschiedlichen begrenzten Kontexten
- kann mit dem Infrastruktur-Services interagieren: OrderCancelled => OrderCancelledHandler => EmailService.sendEmail()
- neue Befehle feuern
- Kann mit Finders sprechen
- Wenn der Event-Handler Befehle absetzt, mit Finders spricht und mit der Infrastruktur interagiert, ähnelt er dem Saga-Verhalten (oder dem REST-Enpoint-Verhalten). Außer es ist die Reaktion auf ein einzelnes Ereignis und nicht auf eine Kette/einen Satz von Ereignissen.
Saga
- Behält einen Geschäftsprozess, der über die gleichen oder mehr begrenzten Kontexte (Koordinaten) sitzt
- empfangen Ereignisse
- Behält den Zustand einer Kette/Satz von Ereignisse
- Normalerweise wird der Status beibehalten
- Timeouts können eingestellt werden, um Status zu überprüfen/zu ändern (kann Vorstellung von Zeit haben)
- Staaten können Nebenwirkungen haben, wie: Befehle abfeuern, mit Finders sprechen, mit den Infrastrukturdiensten interagieren (z.B.E-Mail)
- Zum Beispiel: Warten Sie OrderShipped und orderreceived Ereignisse => Feuer CancelOrderCommand Warten Sie OrderCancelled => Feuer Bestellung storniert E-Mail
Finder
- verwendet, um eine readmodel von abrufen der Kontext (e)
- Liefert im Allgemeinen Datenobjekte vom Typ Objekt (DTO)
- Fin der sollte nicht in der Schreibseite unserer Anwendung (weniger Kopplung)
- Einzel (read + write) normalisierte Datenbankmodell zu finden: der Finder andere Finders aufrufen können (über Kontexte) verschachtelten Objekten zu erfüllen
- Lesen Spezifische De- normalisierte Datenbankmodell: der Finder die Daten alle in einer Datenbank Aufruf
- Zum Beispiel erhalten:
finder.findOrdersOnDate(date);
Infrastructure Services
- Angebote mit Infrastruktur: DB-Zugriff, E-Mails, Nachrichtenwarteschlangen usw.
Frage
Ist dies eine genaue Zusammenfassung der Komponenten vs. Aufgaben? Was fehlt und was sollte bewegt werden? Ich kann die Liste mit relevanten Antworten aktualisieren.
["Implementierung von domänengesteuertem Design"] (https://vaughnvernon.co/?page_id=168) von Vaughn Vernon bietet technische Details, die jede dieser Komponenten abdecken. Ich würde es als eine sehr nützliche Ressource zusätzlich zu Eric Evans Domain-Driven Design empfehlen. –
Zufälligerweise fand ich letzte Nacht einen Artikel von Vaughn Vernon. Sehr interessant! Ich werde das Buch kaufen. Was würdest du der Liste basierend auf dem Buch hinzufügen? –