CQRS i Event Sourcing – kiedy używać i jak zacząć

CQRS i Event Sourcing – kiedy używać i jak zacząć

Architektura oprogramowania ewoluuje, by sprostać rosnącej złożoności i wymaganiom współczesnych aplikacji. Wśród zaawansowanych wzorców projektowych, które zyskują na popularności, są CQRS (Command Query Responsibility Segregation) i Event Sourcing. Chociaż często występują razem, są to odrębne koncepcje, które rozwiązują różne problemy. Zrozumienie, kiedy ich używać i jak zacząć, jest kluczowe dla budowania skalowalnych i elastycznych systemów.

CQRS: Podział odpowiedzialności odczytu i zapisu

CQRS to wzorzec architektoniczny, który polega na rozdzieleniu odpowiedzialności za zapis (commands) i odczyt (queries) danych. W tradycyjnym podejściu (tzw. CRUD – Create, Read, Update, Delete) ten sam model danych i ta sama baza danych są używane zarówno do zapisywania, jak i odczytywania informacji. Wzorce CQRS proponują inne podejście.

W CQRS mamy dwa oddzielne modele:

  • Model zapisu (Command Model): Służy do obsługi operacji zmieniających stan systemu. Przyjmuje komendy (commands), które są intencjami użytkownika (np. „ZmieńCenęProduktu”, „DodajProduktDoKoszyka”). Ten model jest często zoptymalizowany pod kątem spójności i integralności danych, używając skomplikowanej logiki domenowej. Zazwyczaj używa bazy danych, która jest zoptymalizowana do szybkich operacji zapisu.
  • Model odczytu (Query Model): Służy do obsługi zapytań o dane. Zamiast skomplikowanych zapytań, ten model jest zoptymalizowany pod kątem szybkości odczytu. Dane są często zdenormalizowane i przechowywane w formie, która jest idealna dla widoków (np. w bazie NoSQL, takiej jak ElasticSearch).

Kiedy używać CQRS?

  • W aplikacjach z wysokim współczynnikiem odczytu w stosunku do zapisu – gdy dane są czytane znacznie częściej niż modyfikowane. Rozdzielenie modeli pozwala na skalowanie każdego z nich niezależnie.
  • Gdy model zapisu jest złożony, a model odczytu prosty. Na przykład, skomplikowane operacje biznesowe dotyczące zamówień można obsługiwać w modelu zapisu, a proste widoki dla użytkownika można pobierać z zdenormalizowanego modelu odczytu.
  • W architekturze opartej na zdarzeniach, gdzie dane są synchronizowane między modelami za pomocą zdarzeń.

Event Sourcing: Źródło prawdy jako strumień zdarzeń

Event Sourcing to wzorzec, który zakłada, że zamiast przechowywania aktualnego stanu obiektu, przechowujemy strumień zdarzeń (events), które doprowadziły do tego stanu. Każda zmiana w systemie jest zapisywana jako nowe zdarzenie. Aby odtworzyć aktualny stan, wystarczy „odtwarzać” (replay) te zdarzenia w kolejności, w jakiej wystąpiły. Baza danych w tym przypadku staje się logiem zdarzeń (event log).

  • Zdarzenia (Events) są niezmienne – raz zapisane, nigdy nie są modyfikowane ani usuwane. Jest to kluczowa cecha, która sprawia, że Event Sourcing jest doskonałym źródłem audytu.
  • Agregaty (Aggregates) to obiekty, które chronią spójność biznesową w kontekście zmian. To one podejmują decyzje na podstawie zdarzeń, generując nowe zdarzenia.

Kiedy używać Event Sourcing?

  • Gdy śledzenie historii zmian jest krytyczne. Sourcing zdarzeń zapewnia pełny audyt, co jest nieocenione w systemach finansowych, ubezpieczeniowych czy medycznych.
  • W systemach, które muszą odtwarzać stan w przeszłości. Możliwość odtworzenia stanu w dowolnym momencie pozwala na analizę, debugowanie i tworzenie nowych modeli odczytu.
  • W połączeniu z CQRS. Model zapisu oparty na Event Sourcing może być bazą dla wielu różnych modeli odczytu, które są budowane na podstawie tych samych zdarzeń.

Jak zacząć?

Wprowadzenie CQRS i Event Sourcing to proces, który wymaga starannego planowania i zrozumienia.

Jak zacząć z CQRS:

  1. Zidentyfikuj, gdzie jest to potrzebne. Nie musisz stosować CQRS w całym systemie. Zacznij od jednego, skomplikowanego modułu, w którym tradycyjny model CRUD jest problemem.
  2. Rozdziel model odczytu i zapisu. Na początku możesz użyć tej samej bazy danych, ale z dwoma różnymi modelami (np. DTO dla odczytu i encje dla zapisu). To pozwoli Ci zrozumieć koncepcję, zanim przejdziesz do oddzielnych baz.
  3. Synchronizuj dane. Gdy już masz dwa modele, musisz zaimplementować mechanizm synchronizacji. W prostym przypadku może to być prosty proces uruchamiany po zapisie danych. W bardziej zaawansowanych scenariuszach, zdarzenia (events) są idealnym sposobem na komunikację.

Jak zacząć z Event Sourcing:

  1. Skup się na zdarzeniach, a nie na stanie. Zamiast myśleć o tym, jak wygląda dany obiekt w bazie danych, zastanów się, jakie zdarzenia go tworzą i modyfikują. Myśl o zdarzeniach jako o nieodwracalnych faktach.
  2. Wybierz platformę. Wykorzystaj istniejące narzędzia (np. Event Store, Axon Framework, Marten) zamiast budować wszystko od zera. Te platformy oferują gotowe rozwiązania do zarządzania logiem zdarzeń i odtwarzania ich.
  3. Zacznij od prostego agregatu. Stwórz prosty agregat, np. Koszyk, który generuje zdarzenia takie jak ProduktDodanyDoKoszyka, IloscZmieniona, KoszykWyczyszczony. Użyj tych zdarzeń do rekonstrukcji stanu koszyka.

CQRS i Event Sourcing to zaawansowane wzorce, które oferują potężne korzyści w postaci skalowalności, elastyczności i audytowalności, ale wymagają one zmiany sposobu myślenia o architekturze. CQRS rozwiązuje problem braku optymalizacji modeli danych pod kątem odczytu i zapisu, a Event Sourcing zapewnia niezmienny, audytowalny log wszystkich zmian w systemie. Największe korzyści można osiągnąć, łącząc oba te wzorce, gdzie Event Sourcing służy jako trwałe źródło prawdy dla modelu zapisu, a CQRS umożliwia tworzenie wielu zoptymalizowanych modeli odczytu na podstawie tego samego strumienia zdarzeń. Pamiętaj, aby wprowadzać te wzorce stopniowo i tam, gdzie faktycznie są potrzebne, unikając niepotrzebnej złożoności w prostych systemach.

Face 4
Mirek Drzewiecki

Jestem programistą z wieloletnim doświadczeniem w branży IT. Od zawsze fascynują mnie nowe technologie, a moją misją jest dzielenie się wiedzą i pomaganie innym developerom w rozwoju. Na co dzień tworzę poradniki, analizuję trendy i testuję narzędzia, które ułatwiają pracę programistom. Uważam, że ciągłe doskonalenie umiejętności oraz wymiana doświadczeń to klucz do sukcesu w świecie technologii.