Command vs Event

Zazwyczaj zakłada się, że komenda (command) jest wysyłana synchronicznie przez Rest API. Zdarzenie (event) natomiast jest wysyłane asynchronicznie za pośrednictwem brokera wiadomości, np. Apache Kafka. W architekturze opartej na wiadomościach (ang. Message Driven Architecture) zarówno komenda jak i zdarzenie będą wysyłane za pośrednictwem brokera wiadomości. Na tym właśnie przypadku skupię się w tym wpisie.

Zacznijmy od tego, że zarówno komenda jak i zdarzenie to rodzaje wiadomości. Z punktu widzenia message brokera nie ma różnicy między tymi dwoma rodzajami wiadomości. Jednak w logice biznesowej i w kodzie naszej aplikacji ta różnica już jest!
Czyli wiadomości możemy podzielić na komendy i zdarzenia:

Na początek spróbuję wyjaśnić różnice między command a event na jakimś życiowym przykładzie. Command, jak sama nazwa wskazuje, jest poleceniem/rozkazem skierowanym do jednej konkretnej osoby. Na przykład: „Marek, wypij!”. Natomiast event jest informacją, że coś się wydarzyło. Na przykład: „Marek wypił” – czas przeszły. W przypadku eventu, w przeciwności do komendy, nie wiadomo, ile jest odbiorców i czy jacyś w ogóle są. Przykładowo, gdy Marek wypił, to Asia może się obrazić, Bartek może stwierdzić, że jeśli Marek wypił, to on też wypije. A może nikt na to nie zareagować. Co więcej, komenda może zostać odrzucona, Marek może powiedzieć, że dziś nie pije.

Jaka jest różnica między Command a Event w Message Driven Architecture?

CommandEvent
DefinicjaWydanie rozkazuInformacja, że coś się wydarzyło
NadawcaWie, do kogo adresuje polecenieNie zna odbiorców i nie wie, czy są
Odbiorca1 z góry określony przez nadawcę0 lub wiele, każdy, kto jest zainteresowany, może nasłuchiwać
NazewnictwoCzasownik w trybie rozkazującymInformacja w czasie przeszłym
PrzykładChangeUserPasswordUserPasswordChanged

Jak widać z powyższej tabelki komendy i eventy to wiadomości, które mają inne przeznaczenia. Oczywiście, mogą one działać razem w jednym systemie. Na przykład, komenda createUser zleci utworzenie użytkownika, a po utworzeniu użytkownika zostanie wyemitowany event userCreated, na który mogą nasłuchiwać zainteresowani, np. serwis lojalnościowy, aby przyznać rabat, serwis statystyk dodać wpis do bazy, może jakaś replikacja części danych użytkownika w innych serwisach, itd. Więc to nie tylko semantyka, ale rozdzielenie tych wiadomości może być kluczowe dla implementacji naszej aplikacji.

Trzymając się przykładu tworzenia użytkownika, załóżmy, że teraz po utworzeniu użytkownika chcemy mu wysłać powiadomienie „Siemanko Marcin! Fajnie, że się zarejestrowałeś”. Czyli dochodzi kolejna usługa do naszej architektury, odpowiedzialna za wysyłanie notyfikacji. Obsługa tego za pomocą komendy wymaga implementacji notification-servicei implementacji wysyłania komendy w user-service, czyli w dwóch miejscach. Z kolei, w przypadku korzystania z eventu nie ma potrzeby zmiany w istniejącej architekturze, dochodzi notification-service, który czyta sobie już wcześniej generowane zdarzenie userCreated – implementacja tylko nowej usługi. W przypadku architektury mikroserwisów, gdzie różne serwisy mogą być utrzymywane przez różne zespoły, ma to kluczowe znaczenie. Dlatego eventy zawsze będą bardziej asynchroniczne i będą dawały większą elastyczność podczas rozwoju aplikacji. Niestety, nie wszystko da się ogarnąć eventami. 🙂

Podsumowując, warto znać różnicę między eventami a komendami, ponieważ pozwala nam to lepiej modelować naszą aplikację.
Jeśli ten wpis okazał się dla Ciebie wartościowy, daj znać w komentarzu. Jeśli chcesz zobaczyć w praktyce różnicę event vs command, to zapraszam Cię do mojego innego wpisu. Dotyczy on wzorca Sagi -> Wzorzec Saga.

One thought on “Command vs Event

  1. Cześć, dzieki za świetną robotę którą tu robisz. Tworzysz bardzo pomocne materiały, także dla ambitnego juniora jak ja.
    Przystępny język, życiowe przykłady – tak 3maj!
    Pozdrawiam

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Zacznij wpisywać wyszukiwane hasło powyżej i naciśnij Enter, aby wyszukać. Naciśnij ESC, aby anulować.

Do góry