{"componentChunkName":"component---src-templates-blog-post-js","path":"/blog/mikroserwisy-rodzaje-zdarzen","result":{"data":{"markdownRemark":{"html":"<p>Termin <em>zdarzenie</em> ma w programowaniu wiele znaczeń. Kiedyś mógł być kojarzony głównie z UI - wydarzenia (<em>eventy</em> ;) ) dotyczyły interakcji użytkownikiem, np. kliknięcia przeń w dany przycisk. W świecie mikroserwisów, DDD itp. - to znaczenie jednak się zmieniło (a może rozszerzyło). Dziś tych zakresów znaczeniowych jest więcej, mogą się one mieszać i nie zawsze wiadomo, o jaki rodzaj <em>eventu</em> chodzi. Na przykładzie projektu, w którym pracowałem, a który był oparty o \"referencyjną\" architekturę <a href=\"https://github.com/dotnet-architecture/eShopOnContainers\">eShopOnConatiners</a> (czyli Microsoftowego przykładu rozwiązania mikroserwisowo-kontenerowego) - będę chciał pokazać typologię różnych znaczeń terminu <em>zdarzenie</em>.</p>\n<h1>Zdarzenie w ramach encji</h1>\n<p>Gdy stosujemy <em>event sourcing</em>, to w zasadzie wszelkie zmiany stanu domeny dzieją się za pomocą zdarzeń. Gdy zamówienie zostało złożone (<code class=\"language-text\">OrderWasCreated</code>), gdy zamówienie zostało opłacone (<code class=\"language-text\">OrderWasPaid</code>), gdy zamówienie zostało anulowane (<code class=\"language-text\">OrderWasCancelled</code>) i tak dalej. Te wydarzenia w zasadzie mapują się na wydarzenia, które możemy rozpoznać podczas sesji <em>event stormingu</em>. One też są zapisywane w <em>event store</em>.\nO ile dobrze przejrzałem projekt eShopOnContainers, nie ma tam takich zdarzeń, jednak spotkałem się z takim rozwiązaniem właśnie w przypadku serwisu implementującego <em>event sourcing</em>.</p>\n<h1>Zdarzenia domenowe</h1>\n<p>Jeśli stosujemy <em>event sourcing</em>, być może to rozróżnienia na zdarzenia \"wewnątrz encji\" i \"domenowe\" wydaje się bez sensu, ale w przypadku modelowania DDD, ale bez <em>event sourcingu</em>, nie będziemy mieć tych pierwszych, ale te drugie - już tak. Otóż, gdy zachodzi potrzeba reakcji jednego agregatu na zmianę w drugim agregacie - wówczas możemy posłużyć się takim zdarzeniem domenowym. W tym przykładowym repozytorium <a href=\"https://github.com/dotnet-architecture/eShopOnContainers\">eShopOnConatiners</a> reprezentowane są one przez klasy z sufiksem <code class=\"language-text\">-DomainEvent</code>.\nIch rolą jest \"komunikacja\" pomiędzy agregatami. Być może słowo \"komunikacja\" nie jest precyzyjne, gdyż mamy tu do czynienia raczej ze schematem producent oraz potencjalnie wielu konsumentów. Kiedy takie zdarzenie może być potrzebne? Jak wiadomo, agregaty nie mają możliwości wprost wywoływania swoich metod - byłyby wówczas ze sobą powiązane. Jeśli mamy np. skompilkowaną strukturę zarządzania magazynu, gdzie dostawa wymaga obsługi zarówno przez agregat <code class=\"language-text\">Warehouse</code> (np. ulokowanie paczki w odpowiednim miejscu fizycznego magazynu), ale też poinformowania agregatu <code class=\"language-text\">StockProduct</code> o zwiększeniu ilości stanu magazynowego - wówczas z agregatu <code class=\"language-text\">Warehouse</code> możemy wywołać wydarzenie <code class=\"language-text\">ProductReceived</code>, który będzie obsłużony przez inny agregat.\nW praktyce przykładu eShopOnContainers wygląda to tak, że każdy agregar zawiera kolekcję \"wydarzeń do opublikowania\", które jest \"opróżniana\" podczas zapisywania encji. Opróżnianie polega zaś na wysłaniu tych wydarzeń do mediatora, co z kolei wymaga napisania handlera dla takiego wydarzenia, w którym możemy zawołać metodę z innego agregatu. W efekcie uzyskujemy też to, że cała operacja jest wykonywana w transakcji (a przynajmniej może być) - ma to swój plus, gdyż nie ma możliwości, żeby takie wydarzenie gdzieś utknęło (dostawa dotarła do magazynu, ale nie został zwiększony stan magazynowy), ale z drugiej strony - błędy w handlerach powodują, że nie można wykonać \"pierwotnej\" operacji (z powodu wyjątku).</p>\n<h1>Zdarzenia integracyjne</h1>\n<p>eShopOnContainers operuje też trzecim typem wydarzeń - patrz klasy z sufiksem <code class=\"language-text\">-IntegrationEvents</code>. To są zdarzenia, które służą do poinformowania innych mikroserwisów o - <em>nomen omen</em> - wydarzeniach w ramach pojedynczego serwisu. Przykładowo, gdy użytkownik został oznaczony jako \"oszust\", serwis <code class=\"language-text\">Users</code> powinien poinformować o tym inne serwisy: na przykład serwis <code class=\"language-text\">Orders</code> może anulować wszystkie jego zamówienia i wstrzymać wysyłkę produktów.\nW tym przykładowy repo jest to realizowane za pomocą Service Bus: serwisy \"wrzucają\" wydarzenia integracyjne na odpowiednie \"tematy\" na szynie, natomiast inne serwisy, zainteresowane danymi wydarzeniami, zawczasu subskrybują się na nie i zapewniają swój kod do obsługi takiego wydarzenia.</p>","excerpt":"Termin zdarzenie ma w programowaniu wiele znaczeń. Kiedyś mógł być kojarzony głównie z UI - wydarzenia (eventy ;) ) dotyczyły interakcji użytkownikiem, np…","frontmatter":{"date":"01 June, 2021","path":"/blog/mikroserwisy-rodzaje-zdarzen","title":"Mikroserwisy: rodzaje zdarzeń"},"fields":{"readingTime":{"text":"3 min read"}}}},"pageContext":{}},"staticQueryHashes":["3649515864","63159454"]}