CQRS/ES - Pytanie

1

Cześć,

Właśnie projektuję sobie testową aplikację z wykorzystaniem architektury CQRS/ES. Napotkałem jednak problemy na które nie umiem znaleźć odpowiedzi(może źle wpisuję w google). Ale do rzeczy, przedstawię to na prostym przykładzie bloga.
Jest sobie blog, autorzy dodają sobie artykuły etc. Jest też administrator który czuwa nad ich treściami, i może banować autorów. Po zbanowaniu autora wszystkie jego artykuły mają być niedostępne. No właśnie, i tutaj mam problem, bo o ile łatwo zmienić agregat autora, poprzez zmienienie jego stanu na zbanowanego(atrybut true/false) nie do końca rozumiem jak mam oznaczyć wszystkie jego artykuły jako niedostępne(niedostępne, czyli usuwam je z bazy danych zawierającą projekcje - read modele). Miałem 2 pomysły:

  1. W command handlerze emituję kilka eventów które banują autora(1 event), oraz artykuły(n eventów)
  2. Tworzę sobie process manager który po wyemitowaniu eventu do zbanowania autora zmieni stan artykułów
    W tych dwóch rozwiązaniach jest tylko jeden problem. Skąd mam zabrać identyfikatory wszystkich agregatów dla artykułu. Czy mogę sobie je wyciągnąć poprzez zapytanie bazy danych z read modelami o wszystkie id artykułów dla danego autora?
1

Jesli wystarczy Ci samo zbanowanie autora (w sensie wyslanie w "swiat" eventu o jego zbanowaniu) bez odpowiedniego eventu dla kazdego artykulu, to w denormaliserze gdzie tworzysz read model skonsumuj ten event i usun odpowiednio wszystkie artykuly tego autora. Ewentualnie dla kazdego eventu o usunietym artykule, usun ten artykul z read modelu.

Skąd mam zabrać identyfikatory wszystkich agregatów dla artykułu.

Nie wiem jak wyglada Twoj read model, ale czy artykuly nie powinny miec ID autora? W takim przypadku wystarczylo by usuniecie/zmiana stanu artykulu na podstawie ID autora.

Tworzę sobie process manager który po wyemitowaniu eventu do zbanowania autora zmieni stan artykułów

Chyba mylisz czym jest process manager. Process manager na pewno nie powinien zmieniac zadnego stanu artykulow! Logika biznesowa nie jest odpowiedzialnoscia process managerow. Process Manager jest jedynie od koordynacji dzialan agregatow. Zachecam do lektury

You should not use a process manager to implement any business logic in your domain. Business logic belongs in the aggregate types.

EDIT: Żeby bardziej to zobrazować, process manager powinien konsumowac eventy i emitować polecenia, czyli event -> command. W Twoim przypadku byłoby to coś w stylu: AuthorBanned -> RemoveArticlesForAuthor

0

@Aventus: Dzięki za odpowiedź. Jednak trochę podałem zły przykład. Chciałbym żeby zbanowane artykuły nie zostały usunięte z bazy danych projekcji, ale zmieniły swój atrybut na coś w rodzaju "zbanowany". i teraz chciałbym żeby agregat tego artykułu miał też ustawiony taki atrybut na "zbanowany". Nie wiem ale o ile się nie mylę nie powinno się czerpać stanu z bazy projekcji, dlatego myślę że mógłbym zapisywać wszystkie id artykułów w agregacie autora(jako tablica identyfikatorów)?

Chyba mylisz czym jest process manager

Tutaj dobrze rozumiem czym jest process manager :)

fakt, napisałem

...eventu do zbanowania autora zmieni stan artykułów

Chodziło mi że on sam nie zmieni stanu tych artykułów, tylko wyda odpowiednie komendy do zmiany stanu :)

1

@Aventus: Dzięki za odpowiedź. Jednak trochę podałem zły przykład. Chciałbym żeby zbanowane artykuły nie zostały usunięte z bazy danych projekcji, ale zmieniły swój atrybut na coś w rodzaju "zbanowany". i teraz chciałbym żeby agregat tego artykułu miał też ustawiony taki atrybut na "zbanowany".

Jesli chodzi nie o usuwanie, a ustawianie odpowiedniego "stanu" (flagi) artykulow to zaproponowane przeze mnie podejscie sie nie zmienia. Nadal emitujesz eventy, i na ich podstawie ustawiasz odpowiednio flage w read modelu.

Nie wiem ale o ile się nie mylę nie powinno się czerpać stanu z bazy projekcji, dlatego myślę że mógłbym zapisywać wszystkie id artykułów w agregacie autora(jako tablica identyfikatorów)?

Jesli dobrze rozumiem Twoj model i wymagania transakcyjnosci w obrebie kontekstu (ban autora skutkuje "banem" artykulow), to Autor powinien byc aggregate root trzymajacy wszystkie swoje artykuly. Wtedy, wywolujac metode banujaca Autora, Autor iteruje po swoich artykulach i rowniez je banuje. Nie za bardzo rozumiem do konca o co chodzi z tym stanem z projekcji- stan agregatow ladujesz poprzez rehydrate za pomoca eventow. Mozna rowniez zastosowac wzorzec memento.

Chodziło mi że on sam nie zmieni stanu tych artykułów, tylko wyda odpowiednie komendy do zmiany stanu :)

Ok, opacznie to odebralem.

1

Ok, dobra już zrozumiałem :) Wielkie dzięki @Aventus

1 użytkowników online, w tym zalogowanych: 0, gości: 1