Jak powinniśmy tworzyć nowe zagregowane korzenie w architekturze cqrs? W tym przykładzie chcę utworzyć nowy zagregowany katalog główny AR2, który będzie zawierał odniesienie do pierwszego AR1.
Tworzę AR2 przy użyciu metody AR1 jako punktu wyjścia. Jak dotąd widzę kilka opcji:
- Wewnątrz metody w AR1
createAr2RootOpt1
mogłemnew AR2()
natychmiast wywołać i zapisać ten obiekt w db za pomocą usługi domeny, która ma dostęp do repozytorium. Mógłbym emitować zdarzenie w pierwszym zbiorczym katalogu głównym np.
SholdCreateAR2Event
a następnie mają bezpaństwową sagę, która reaguje na to i wydaje polecenie,CreateAR2Command
które jest następnie obsługiwane i faktycznie tworzy AR2 i emitujeAR2CreatedEvent
. W przypadku korzystaniaSholdCreateAR2Event
ze źródła zdarzeń nie będzie zachowane w magazynie zdarzeń, ponieważ nie wpływa to na stan pierwszego zagregowanego katalogu głównego. (Czy powinniśmy nadal to zapisywać w sklepie z wydarzeniami?)class AR1{ Integer id; DomainService ds; //OPTION 1 void createAr2RootOpt1(){ AR2 ar2 = new AR2(); ds.saveToRepo(ar2); } //OPTION 2 void createAr2RootOpt2(){ publishEvent(new SholdCreateAR2Event()); //we don't need this event. Shoud it still be preserved in event store? } } class AR2{ Integer id; Integer ar1Id; void handle(CreateAR2Command command){ //init this AR with values and save publishEvent(AR2CreatedEvent()); //used for projections afterwards and saved inside AR2 event store } } class Saga{ void handle(SholdCreateAR2Event ev){ emitCommand(new CreateAR2Command()); } }
Który sposób jest bardziej odpowiedni?
AR1WasCreated
? Powinno byćAR2WasCreated
? Ponadto, jeśli użyję waszej logiki, wysyłam zdarzenie,AR2WasCreated
zanim zostanie ono faktycznie utworzone? I zapisywanie tego zdarzenia w dzienniku zdarzeń AR1 wydaje się problematyczne, ponieważ tak naprawdę nie potrzebuję tych danych w AR1 (nie modyfikuje niczego w AR1).