Cześć. Wyobraźmy sobie, że mamy dość sporą apkę mikroserwisową z ładnie odseparowanymi DB z PGSQL (uwzględniłem to, bo pracowałem w banku, gdzie były MSy na wspólnej DB i fajnie, łatwo robiło się CQRS.. oczywiście nie zważając na wady wspólnej bazy w tym przypadku).
Żeby nie zagłębiać się super w domenę tej apki na warsztat weźmy trzy mikroserwisy - item , customer oraz search. Item to jakiś tam produkt w sklepie, customer to wiadomo - kupujący lub sprzedający, a search to mikroserwis nasłuchujący na zdarzenia domenowe i zapisujący sobie dane w elasticsearchu, które potem łatwo można szukać poprzez jakieś filtrowania.
Mamy sobie dwa ekrany na UI:
- Lista produktów z różnymi filtrami szukającymi
- Ekran szczegółów produktu
Póki co agregowanie danych na tych ekranach jest rozwiązane w ten sposób:
-
Na podstawie filtrów idzie request do search service, który przeszukuje sobie elasticsearcha i zwraca listę IDków itemów (mimo, że ma część danych każdego itemu na potrzeby filtrowania), a następnie idzie drugi request już do item service z tymi id po listę itemów z większą ilością danych.
-
Tutaj wejściem jest id itemu i następuje ok 5 zapytań do kilku różnych mikroserwisów po potrzebne dane. Czyli najpierw idzie request po detale itemu, następnie idzie request po detale sprzedawcy (jak już znamy sellerId z pierwszego requestu) i potem kaskadowo po inne potrzebne dane (niektóre oczywiście idą równolegle). Generalnie logika tam na froncie jest dość skomplikowana - po prostu front jest agregatem danych.
Czy na te dwa ekrany (i wiele innych w systemie gdzie agregujemy dane z wielu MS) CQRS byłbym dobrym rozwiązaniem?
-
Sprawę z search service można załatwić w trochę odwrotny sposób - mógłby nasłuchiwać na dedykowany dla siebie rozszerzony event ze WSZYSTKIMI danymi danego itemu. Wtedy nie musimy uderzać z listą id do item service tylko po prostu search service jest naszym wejściem do części query.
-
Wykorzystać search service, utworzyć w nim jakiś read model typu ItemDetails zawierający wszystkie dane potrzebne na tamtym ekranie i potworzyć nowe dedykowane eventy typu UserUpdated, AddressUpdated. Wtedy na ekranie Item Details nie musimy robić 5 requestów po dane tylko jeden do tego search service.
Jakie mam wątpliwości i pytania..
-
Już teraz istnieje mi w systemie event ItemAdded/ItemUpdated z biznesowymi danymi, na które nasłuchują inne biznesowe MSy. Jeśli miałbym dołożyć nowy event emitowany przy dodaniu, edycji itemu to powinienem rozszerzyć ten istniejący czy dodać zupełnie nowy i emitować po prostu dwa eventy? Oczywiście pytam tu nie tylko o kontekst itemu, ale o resztę, którą będzie ten search używał do agregowania danych.
-
Jak zasilić search service o istniejące dane po wprowadzeniu featura aby doprowadzić do jego spójności z resztą? No bo teraz on np. nie słucha na Usera, a musiałby,
-
Jakie są strategie sprawdzania spójności i naprawiania ewentualnych braków? Zawsze event może nie dojść, albo coś innego może się sypnąć.
-
Czy to jest w ogóle dobry pomysł?
Bambo