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:
- 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.
- 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.
- 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:
- 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.
- 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.
- Zacznij od prostego agregatu. Stwórz prosty agregat, np.
Koszyk, który generuje zdarzenia takie jakProduktDodanyDoKoszyka,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.




