<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	 xmlns:media="http://search.yahoo.com/mrss/" >

<channel>
	<title>Application development &#8211; Nearshore Software Development Company &#8211; IT Outsourcing Services</title>
	<atom:link href="https://nearshore-it.eu/pl/tag/application-development/feed/" rel="self" type="application/rss+xml" />
	<link>https://nearshore-it.eu/pl/</link>
	<description>We are Nearshore Software Development Company with 14years of experience in delivering a large scale IT projects in the areas of PHP, JAVA, .NET, BI and MDM.</description>
	<lastBuildDate>Tue, 27 Jan 2026 08:25:50 +0000</lastBuildDate>
	<language>pl-PL</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>

<image>
	<url>https://nearshore-it.eu/wp-content/uploads/2023/01/cropped-inetum-favicon-300x300-1-32x32.png</url>
	<title>Application development &#8211; Nearshore Software Development Company &#8211; IT Outsourcing Services</title>
	<link>https://nearshore-it.eu/pl/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Azure Service Bus – usługa, która usprawnia obsługę komunikatów i kolejki w nowoczesnych aplikacjach</title>
		<link>https://nearshore-it.eu/pl/artykuly/azure-service-bus/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/azure-service-bus/#respond</comments>
		
		<dc:creator><![CDATA[Bartosz Brandt]]></dc:creator>
		<pubDate>Mon, 26 Jan 2026 14:30:09 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Application development]]></category>
		<category><![CDATA[Cloud engineering]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/?p=37834</guid>

					<description><![CDATA[Azure Service Bus to dojrzały broker komunikatów klasy enterprise, który w ekosystemie Microsoft Azure odpowiada za niezawodną komunikację między mikroserwisami i systemami zewnętrznymi. Artykuł pokazuje, jak kolejki, topics, subskrypcje i sesje pozwalają budować systemy odporne na przeciążenia i awarie oraz dlaczego wzorce takie jak publish/subscribe, request–response, outbox i inbox są dziś fundamentem architektury event-driven. Jeśli projektujesz skalowalne aplikacje i chcesz świadomie wybrać model komunikacji — ten materiał pomoże Ci podjąć właściwe decyzje architektoniczne.]]></description>
										<content:encoded><![CDATA[
<p>Podczas tworzenia nowoczesnych aplikacji coraz rzadziej wybierana jest architektura monolityczna. W dzisiejszych czasach znacznie częściej są to modularne monolity lub <a href="https://nearshore-it.eu/pl/artykuly/mikroserwisy-nowa-jakosc-w-miedzynarodowych-projektach-it/">mikroserwisy</a>. Często również spotykamy integracje z systemami zewnętrznymi oraz architekturę event-driven, które sprawiają, że kluczowym elementem staje się niezawodna komunikacja pomiędzy komponentami. W ekosystemie Microsoft Azure rolę tę bardzo często pełni usługa Service Bus – dojrzały broker komunikatów klasy enterprise.</p>



<div class="table-of-contents">
    <p class="title"></p>
    <ol>
                    <li><a href="#czym-jest-usluga-service-bus-i-dlaczego-microsoft-stawia-na-komunikaty-w-chmurze">1.  Czym jest usługa Service Bus i dlaczego Microsoft stawia na komunikaty w chmurze?</a></li>
                    <li><a href="#kolejki-topics-i-subskrypcje-oraz-sesje-jak-dziala-usluga-azure-service-bus">2.  Kolejki, Topics i subskrypcje oraz sesje – jak działa usługa Azure Service Bus?</a></li>
                    <li><a href="#azure-service-bus-queue-vs-topic-kiedy-wybrac-ktore-rozwiazanie">3.  Azure Service Bus Queue vs Topic – kiedy wybrać które rozwiązanie?</a></li>
                    <li><a href="#azure-service-bus-patterns-wzorce-ktore-warto-znac">4.  Azure Service Bus Patterns – wzorce, które warto znać</a></li>
                    <li><a href="#monitoring-i-diagnostyka-azure-service-bus-alerts-i-integracja-z-application-insights">5.  Monitoring i diagnostyka: Azure Service Bus Alerts i integracja z Application Insights</a></li>
                    <li><a href="#zabezpieczenia-w-azure-service-bus-rbac-sas-i-protokol-amqp">6.  Zabezpieczenia w Azure Service Bus – RBAC, SAS i protokół AMQP</a></li>
                    <li><a href="#podsumowanie-co-warto-zapamiętać">7.  Podsumowanie – co warto zapamiętać?</a></li>
                    <li><a href="#czesto-zadawane-pytania">8.  Często zadawane pytania</a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="czym-jest-usluga-service-bus-i-dlaczego-microsoft-stawia-na-komunikaty-w-chmurze">Czym jest usługa Service Bus i dlaczego Microsoft stawia na komunikaty w chmurze?</h2>



<p>Azure Service Bus pozwala oddzielić producentów komunikatów od ich konsumentów. Dzięki temu aplikacje nie muszą znać się nawzajem ani działać w tym samym czasie. Komunikaty mogą być bezpiecznie przechowywane, ponawiane i przetwarzane asynchronicznie, co znacząco poprawia stabilność całego systemu.</p>



<p>Z perspektywy architekta jest to jedno z kluczowych narzędzi do budowy systemów odpornych na przeciążenia i chwilowe awarie.</p>



<p>Azure Service Bus to zarządzana usługa message brokera, oferująca:</p>



<ul class="wp-block-list">
<li>kolejki (Queues),</li>



<li>tematy i subskrypcje (Topics &amp; Subscriptions),</li>



<li>transakcje,</li>



<li>obsługę kolejki utraconych wiadomości (dead-letter queue),</li>
</ul>



<p>Nowoczesne systemy IT konsekwentnie promują komunikację asynchroniczną za pomocą kolejek z kilku powodów:</p>



<ul class="wp-block-list">
<li>zwiększa skalowalność,</li>



<li>upraszcza rozwój mikroserwisów,</li>



<li>pozwala niezależnie wdrażać i rozwijać komponenty niezależnie od użytych technologii do ich wytworzenia,</li>



<li>pozwala lepiej wykorzystać zasoby chmurowe dostępne np. w środowisku Microsoft Azure.</li>
</ul>



<h2 class="wp-block-heading" id="kolejki-topics-i-subskrypcje-oraz-sesje-jak-dziala-usluga-azure-service-bus">Kolejki, Topics i subskrypcje oraz sesje – jak działa usługa Azure Service Bus?</h2>



<h3 class="wp-block-heading">Service Bus Queue – kolejki usługi service bus</h3>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="756" height="620" src="https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_1.png" alt="Service Bus Queue – kolejki usługi service bus " class="wp-image-37838" title="Azure Service Bus – usługa, która usprawnia obsługę komunikatów i kolejki w nowoczesnych aplikacjach 1" srcset="https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_1.png 756w, https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_1-300x246.png 300w, https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_1-482x395.png 482w" sizes="(max-width: 756px) 100vw, 756px" /></figure></div>


<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Kolejki w Azure Service Bus realizują model <strong>point-to-point</strong>, w którym każdy komunikat trafia do kolejki i jest przetwarzany <strong>przez jednego konsumenta</strong>. Nadawca i odbiorca są od siebie niezależni – komunikaty mogą być wysyłane i odbierane w różnym czasie, co zwiększa odporność systemu na awarie i chwilowe przeciążenia.</p>



<p>Usługa wykorzystuje mechanizm <strong>Peek-Lock</strong>, który tymczasowo blokuje komunikat po jego odebraniu. Dopiero po poprawnym przetworzeniu jest on usuwany z kolejki. W przypadku wystąpienia błędu może zostać ponownie udostępniony innemu odbiorcy lub trafić do <strong>dead-letter queue</strong>, co ułatwia diagnostykę problemów. Mechanizm Peek-Lock pozwala konsumentowi tymczasowo zablokować komunikat w kolejce. W przypadku wygaśnięcia blokady (np. z powodu timeoutu), komunikat staje się dostępny dla innych konsumentów, co może prowadzić do powtórnego odbioru.</p>



<p>Jedna kolejka może być obsługiwana przez wiele instancji konsumentów. Azure Service Bus automatycznie rozdziela komunikaty pomiędzy nich, zapewniając <strong>naturalny load balancing</strong> bez dodatkowej logiki po stronie aplikacji.</p>



<p>Kolejki sprawdzają się szczególnie dobrze w scenariuszach takich jak:</p>



<ul class="wp-block-list">
<li>przetwarzanie zadań w tle,</li>



<li>kolejkowanie żądań i ochrona systemów przed przeciążeniem,</li>



<li>równoważenie obciążenia pomiędzy wieloma instancjami usług,</li>



<li>asynchroniczna integracja systemów.</li>
</ul>



<h3 class="wp-block-heading">Topics i subskrypcje</h3>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="756" height="1080" src="https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_2.png" alt="Topics i subskrypcje " class="wp-image-37841" title="Azure Service Bus – usługa, która usprawnia obsługę komunikatów i kolejki w nowoczesnych aplikacjach 2" srcset="https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_2.png 756w, https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_2-210x300.png 210w, https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_2-277x395.png 277w" sizes="(max-width: 756px) 100vw, 756px" /></figure></div>


<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Topics w Azure Service Bus realizują wzorzec <strong>publish/subscribe</strong>, w którym jeden komunikat może zostać dostarczony do <strong><a href="https://nearshore-it.eu/pl/artykuly/systemy-rozproszone-niezalezne-od-platformy-wprowadzenie-do-dapr-io/" data-type="link" data-id="https://nearshore-it.eu/pl/artykuly/systemy-rozproszone-niezalezne-od-platformy-wprowadzenie-do-dapr-io/">wielu niezależnych odbiorców</a></strong>. Producent wysyła komunikat do tematu (Topic), nie wiedząc, kto i ile systemów będzie go konsumować. Każda subskrypcja działa jak osobna kolejka, posiadająca własny stan, retry oraz dead-letter queue.</p>



<p>Największą zaletą Topics są <strong>subskrypcje z filtrami</strong>, które pozwalają określić, jakie komunikaty trafią do danego odbiorcy. Filtry SQL lub reguły oparte o właściwości komunikatu umożliwiają precyzyjne routowanie zdarzeń bez dodatkowej logiki po stronie producenta.</p>



<p>Każda subskrypcja może być obsługiwana przez wiele instancji konsumentów, co, podobnie jak w przypadku kolejek, umożliwia<strong> równoległe przetwarzanie i load balancing</strong>. Jednocześnie różne subskrypcje mogą przetwarzać ten sam komunikat w zupełnie inny sposób lub w innym tempie.</p>



<p>Topics i subskrypcje sprawdzają się szczególnie dobrze w scenariuszach takich jak:</p>



<ul class="wp-block-list">
<li>architektura event-driven,</li>



<li>propagacja zdarzeń domenowych,</li>



<li>integracja wielu systemów reagujących na te same zdarzenia,</li>



<li>oddzielenie logiki biznesowej od procesów pomocniczych (np. powiadomień, audytu, raportowania).</li>
</ul>



<p>Dzięki modelowi publish/subscribe Azure Service Bus Topics umożliwiają budowę elastycznych i łatwo rozszerzalnych systemów, w których dodanie nowego odbiorcy nie wymaga zmian po stronie nadawcy.</p>



<h3 class="wp-block-heading">Sesje</h3>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="756" height="560" src="https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_3.png" alt="Sesje - Azure Service Bus" class="wp-image-37844" title="Azure Service Bus – usługa, która usprawnia obsługę komunikatów i kolejki w nowoczesnych aplikacjach 3" srcset="https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_3.png 756w, https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_3-300x222.png 300w, https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_3-495x367.png 495w" sizes="(max-width: 756px) 100vw, 756px" /></figure></div>


<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Sesje w Azure Service Bus to mechanizm umożliwiający <strong>grupowanie powiązanych komunikatów</strong> i przetwarzanie ich w <strong>ściśle określonej kolejności</strong>. Każdy komunikat posiada SessionId, a wszystkie komunikaty z tym samym identyfikatorem trafiają do tej samej sesji i są obsługiwane sekwencyjnie przez jednego konsumenta.</p>



<p>W praktyce oznacza to, że choć kolejka lub subskrypcja może być przetwarzana równolegle przez wiele instancji odbiorców, to <strong>w ramach jednej sesji nigdy nie dochodzi do przetwarzania równoległego</strong>. Azure Service Bus blokuje sesję na czas jej obsługi przez konkretnego konsumenta, co eliminuje problemy z kolejnością i <a href="https://nearshore-it.eu/pl/artykuly/pulapki-wspolbieznosci-narzut-synchronizacji-watkow/">współbieżnością</a>.</p>



<p>Sesje są szczególnie przydatne w scenariuszach, gdzie:</p>



<ul class="wp-block-list">
<li>kolejność komunikatów ma znaczenie (np. workflow, procesy krok po kroku),</li>



<li>komunikaty dotyczą jednego obiektu biznesowego (np. OrderId),</li>



<li>wymagane jest przetwarzanie stanowe (stateful processing),</li>



<li>system musi zachować spójność bez skomplikowanej synchronizacji.</li>
</ul>



<p>Sesje mogą być używane zarówno w Queue, jak i w subskrypcjach Topiców. Dzięki nim Azure Service Bus łączy wysoką skalowalność z kontrolą kolejności, co jest trudne do osiągnięcia w klasycznych systemach kolejkowych bez dodatkowej logiki po stronie aplikacji.</p>



<h2 class="wp-block-heading" id="azure-service-bus-queue-vs-topic-kiedy-wybrac-ktore-rozwiazanie">Azure Service Bus Queue vs Topic – kiedy wybrać które rozwiązanie?</h2>



<p>Wybór pomiędzy <strong>Queue</strong> a <strong>Topic</strong> w Azure Service Bus zależy przede wszystkim od tego, <strong>ile systemów ma przetwarzać dany komunikat</strong> i w jaki sposób ma on być obsłużony.</p>



<p>Queue najlepiej sprawdzi się w scenariuszach typu point-to-point, gdzie komunikat ma zostać przetworzony dokładnie raz przez jeden komponent. Jest to idealne rozwiązanie dla zadań w tle, kolejkowania żądań czy równoważenia obciążenia pomiędzy wieloma instancjami tej samej usługi. Queue upraszcza architekturę i minimalizuje liczbę zależności pomiędzy komponentami.</p>



<p>Topic warto wybrać wtedy, gdy komunikat reprezentuje zdarzenie, na które powinno zareagować wiele niezależnych systemów. Dzięki subskrypcjom i filtrom możliwe jest selektywne dostarczanie komunikatów do różnych odbiorców bez modyfikowania producenta. Topic naturalnie wspiera architekturę event-driven i ułatwia dalszą rozbudowę systemu.</p>



<p>W praktyce często stosuje się oba mechanizmy jednocześnie:</p>



<ul class="wp-block-list">
<li>Queue do obsługi zadań i procesów technicznych,</li>



<li>Topic do publikowania zdarzeń domenowych.</li>
</ul>



<p>Dobrze dobrany model komunikacji upraszcza architekturę i pozwala skalować system bez kosztownych refaktoryzacji w przyszłości.</p>



<h2 class="wp-block-heading" id="azure-service-bus-patterns-wzorce-ktore-warto-znac">Azure Service Bus Patterns – wzorce, które warto znać</h2>



<h3 class="wp-block-heading"><strong>Azure&nbsp;Service Bus&nbsp;Request-Response&nbsp;pattern</strong></h3>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="756" height="490" src="https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_4.png" alt="Azure Service Bus Request-Response pattern" class="wp-image-37847" title="Azure Service Bus – usługa, która usprawnia obsługę komunikatów i kolejki w nowoczesnych aplikacjach 4" srcset="https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_4.png 756w, https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_4-300x194.png 300w, https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_4-495x321.png 495w" sizes="auto, (max-width: 756px) 100vw, 756px" /></figure></div>


<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Request–Response Pattern w Azure Service Bus umożliwia realizację komunikacji dwukierunkowej w sposób <strong>asynchroniczny</strong>, bez konieczności bezpośredniego połączenia pomiędzy nadawcą a odbiorcą. Zamiast klasycznego wywołania synchronicznego (np. HTTP), klient wysyła komunikat z żądaniem do kolejki lub tematu, a odpowiedź otrzymuje jako osobny komunikat.</p>



<p>W praktyce klient wysyła żądanie do <strong>Request Queue</strong>, dołączając informacje pozwalające na korelację odpowiedzi (np. CorrelationId lub nazwę kolejki odpowiedzi). Usługa odbierająca żądanie przetwarza je w swoim tempie i publikuje wynik do Response Queue, z której klient odbiera odpowiedź.</p>



<p>Takie&nbsp;podejście&nbsp;zapewnia:&nbsp;</p>



<ul class="wp-block-list">
<li>brak blokowania zasobów po stronie klienta,</li>



<li>odporność na opóźnienia i chwilową niedostępność usług,</li>



<li>lepszą skalowalność w porównaniu do komunikacji synchronicznej.</li>
</ul>



<p>Request–Response Pattern sprawdza się szczególnie w scenariuszach, gdzie odpowiedź jest wymagana, ale nie musi być natychmiastowa – np. w integracjach między mikroserwisami, procesach długotrwałych czy komunikacji pomiędzy systemami o różnej wydajności. W połączeniu z mechanizmami Azure Service Bus, takimi jak retry i dead-letter queue, wzorzec ten pozwala budować niezawodne i elastyczne rozwiązania komunikacyjne.</p>



<h3 class="wp-block-heading">Outbox Pattern</h3>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="756" height="490" src="https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_5.png" alt="Outbox Pattern - Azure Service Bus" class="wp-image-37850" title="Azure Service Bus – usługa, która usprawnia obsługę komunikatów i kolejki w nowoczesnych aplikacjach 5" srcset="https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_5.png 756w, https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_5-300x194.png 300w, https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_5-495x321.png 495w" sizes="auto, (max-width: 756px) 100vw, 756px" /></figure></div>


<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Outbox Pattern to wzorzec architektoniczny, który rozwiązuje problem <strong>spójności pomiędzy zapisem danych a publikacją komunikatu</strong>. W systemach opartych na komunikatach często pojawia się ryzyko, że dane zostaną zapisane w bazie, ale zdarzenie nie trafi do brokera (lub odwrotnie). Outbox Pattern eliminuje ten problem.</p>



<p>W praktyce, zamiast wysyłać komunikat bezpośrednio do Azure Service Bus, aplikacja zapisuje go najpierw do tabeli Outbox w tej samej transakcji co dane biznesowe. Dzięki temu zapis danych i „intencja wysłania komunikatu” stają się operacją atomową. Osobny proces (np. background worker) odczytuje wpisy z Outboxa i publikuje je do Azure Service Bus.</p>



<p>Takie podejście zapewnia:</p>



<ul class="wp-block-list">
<li>brak utraty komunikatów,</li>



<li>odporność na awarie sieci i brokera,</li>



<li>możliwość bezpiecznego ponowienia wysyłki.</li>
</ul>



<p>Outbox Pattern jest szczególnie przydatny w architekturze mikroserwisów i systemach event-driven, gdzie zdarzenia domenowe muszą być publikowane w sposób <strong>pewny i powtarzalny</strong>. W połączeniu z mechanizmami Azure Service Bus, takimi jak ponowienia wysyłki czy deduplikacja, stanowi solidną podstawę do budowy niezawodnej komunikacji między systemami. Outbox Pattern szczególnie dobrze współpracuje z bazami danych wspierającymi transakcje, pozwalając na spójne zapisanie danych biznesowych i komunikatu w jednym kroku.</p>



<h3 class="wp-block-heading">Inbox Pattern</h3>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="756" height="540" src="https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_6.png" alt="nearshore 2026.01.20 graphic 6" class="wp-image-37854" title="Azure Service Bus – usługa, która usprawnia obsługę komunikatów i kolejki w nowoczesnych aplikacjach 6" srcset="https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_6.png 756w, https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_6-300x214.png 300w, https://nearshore-it.eu/wp-content/uploads/2026/01/nearshore_2026.01.20_graphic_6-495x354.png 495w" sizes="auto, (max-width: 756px) 100vw, 756px" /></figure></div>


<div style="height:16px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Inbox Pattern to wzorzec architektoniczny, który rozwiązuje problem <strong>wielokrotnego przetwarzania tego samego komunikatu</strong>. W systemach opartych na komunikatach – takich jak Azure Service Bus – ponowne dostarczenie komunikatu jest zachowaniem poprawnym (np. po błędzie lub timeoutach), dlatego aplikacja musi być na to przygotowana.</p>



<p>W praktyce każdy odebrany komunikat jest najpierw rejestrowany w <strong>Inboxie</strong> – najczęściej w postaci zapisu jego unikalnego identyfikatora (MessageId) w bazie danych. Dopiero jeśli komunikat nie był wcześniej przetwarzany, trafia on do logiki biznesowej. Duplikaty są bezpiecznie ignorowane, co zapewnia <strong>idempotentność</strong> operacji.</p>



<p>Inbox Pattern zapewnia:</p>



<ul class="wp-block-list">
<li>ochronę przed skutkami retry i ponownych dostarczeń,</li>



<li>spójność danych w przypadku awarii podczas przetwarzania,</li>



<li>możliwość bezpiecznego skalowania konsumentów.</li>
</ul>



<h2 class="wp-block-heading" id="monitoring-i-diagnostyka-azure-service-bus-alerts-i-integracja-z-application-insights">Monitoring i diagnostyka: Azure Service Bus Alerts i integracja z Application Insights</h2>



<p>Skuteczne wykorzystanie Azure Service Bus w środowisku produkcyjnym wymaga odpowiedniego <strong>monitoringu i diagnostyki</strong>, które pozwalają szybko reagować na problemy z przetwarzaniem komunikatów. Platforma Azure udostępnia w tym zakresie gotowe mechanizmy oparte o Azure Monitor.</p>



<p>Azure Service Bus publikuje szereg metryk, takich jak liczba aktywnych komunikatów, długość dead-letter queue czy czas przetwarzania. Na ich podstawie można konfigurować Alert Rules, które automatycznie powiadomią zespół o potencjalnych problemach, np. rosnącej liczbie komunikatów w kolejce lub błędach po stronie konsumentów.</p>



<p>Dla głębszej diagnostyki Service Bus integruje się z Application Insights, umożliwiając śledzenie komunikatów w kontekście całego przepływu aplikacji. Dzięki korelacji telemetrycznej możliwe jest przeanalizowanie, jak komunikat przechodzi przez kolejne komponenty systemu i gdzie pojawiają się opóźnienia lub błędy.</p>



<p>Połączenie alertów, metryk i telemetryki aplikacyjnej pozwala nie tylko reagować na incydenty, ale także <strong>proaktywnie wykrywać problemy</strong>, zanim wpłyną one na użytkowników końcowych.</p>



<h2 class="wp-block-heading" id="zabezpieczenia-w-azure-service-bus-rbac-sas-i-protokol-amqp">Zabezpieczenia w Azure Service Bus – RBAC, SAS i protokół AMQP</h2>



<p>Azure Service Bus oferuje mechanizmy bezpieczeństwa klasy enterprise, które pozwalają precyzyjnie kontrolować dostęp do komunikatów i chronić komunikację pomiędzy komponentami systemu. Usługa wspiera zarówno nowoczesne uwierzytelnianie oparte o <strong>Azure Active Directory</strong>, jak i tradycyjne mechanizmy kluczy dostępowych.</p>



<p>RBAC (Role-Based Access Control) umożliwia zarządzanie uprawnieniami przy użyciu ról przypisanych do użytkowników, aplikacji i tożsamości zarządzanych. Pozwala to na centralne i spójne zarządzanie dostępem do kolejek, tematów i subskrypcji, bez konieczności przechowywania wrażliwych danych, takich jak hasła czy klucze dostępu, w kodzie aplikacji. W kontekście Azure Service Bus można stosować predefiniowane role – między innymi Data Owner, Data Sender i Data Receiver – które pozwalają na granularne zarządzanie dostępem do wysyłania, odbioru lub pełnego zarządzania zasobami komunikacyjnymi.</p>



<p>Alternatywą lub uzupełnieniem RBAC są <strong>SAS (Shared Access Signatures)</strong>, czyli tokeny dostępu z określonym zakresem uprawnień i czasem ważności. SAS sprawdzają się w scenariuszach integracyjnych, gdzie wymagany jest ograniczony i kontrolowany dostęp do zasobów Service Bus.</p>



<p>Komunikacja z Azure Service Bus odbywa się z wykorzystaniem protokołu <strong>AMQP 1.0</strong>, który zapewnia wysoką wydajność, niezawodność oraz wsparcie dla scenariuszy enterprise. AMQP umożliwia stabilne połączenia, efektywne przesyłanie komunikatów i pełne wykorzystanie zaawansowanych funkcji usługi. Azure Service Bus obsługuje również protokół HTTP jako alternatywę dla AMQP w przypadku aplikacji, które nie wspierają AMQP. Zaleca się jednak korzystanie z AMQP w przypadku systemów wymagających niskiej latencji i trwałych połączeń.</p>



<p>Połączenie RBAC, SAS i AMQP pozwala budować bezpieczne, skalowalne i zgodne z najlepszymi praktykami rozwiązania komunikacyjne w chmurze Azure.</p>



<h2 class="wp-block-heading" id="podsumowanie-co-warto-zapamiętać">Podsumowanie – co warto zapamiętać?</h2>



<p>Azure Service Bus to kluczowe narzędzie komunikacyjne w chmurze Microsoft Azure, pozwalające na tworzenie nowoczesnych aplikacji opartych na architekturze asynchronicznej. Dzięki bogatemu zestawowi funkcji – takich jak kolejki, tematy i subskrypcje, sesje, oraz wsparcie dla wzorców projektowych (Request-Response,<br>Outbox, Inbox) – usługa umożliwia skalowalność, niezawodność i elastyczność systemów.</p>



<p>Zintegrowane mechanizmy bezpieczeństwa (RBAC, SAS, AMQP) oraz zaawansowane monitorowanie (Application Insights, Azure Monitor) gwarantują pełną kontrolę i stabilność rozwiązania, czyniąc je niezbędnym elementem w ekosystemie<br>nowoczesnych aplikacji chmurowych.</p>



<p>Jeżeli temat cię zaciekawił i chcesz korzystać z usługi w swoim projekcie, zajrzyj do <a href="https://learn.microsoft.com/en-us/azure/service-bus-messaging/" target="_blank" rel="noopener">Microsoft Learn</a> na Azure Portal, by uzyskać więcej informacji.</p>



<h2 class="wp-block-heading" id="czesto-zadawane-pytania">Często zadawane pytania:</h2>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1769434111748" class="rank-math-list-item">
<h3 class="rank-math-question "><strong>Co to jest Azure Service Bus i kiedy warto go używać?</strong></h3>
<div class="rank-math-answer ">

<p>Azure Service Bus to zarządzany broker komunikatów klasy enterprise w Microsoft Azure, który umożliwia asynchroniczną komunikację między komponentami systemu, takimi jak mikroserwisy, aplikacje czy zewnętrzne systemy. Warto go używać, gdy:<br />&#8211; Chcesz zwiększyć odporność systemu na przeciążenia i chwilowe awarie.<br />&#8211; Potrzebujesz niezawodnej komunikacji w systemach event-driven lub przy integracji między usługami.<br />&#8211; Tworzysz aplikacje wymagające kolejki, publish-subscribe, transakcyjnego przetwarzania lub obsługi sesji.</p>

</div>
</div>
<div id="faq-question-1769434170038" class="rank-math-list-item">
<h3 class="rank-math-question "><strong>Jakie są różnice pomiędzy kolejkami (Queue) a tematami (Topics) w Azure Service Bus?</strong> </h3>
<div class="rank-math-answer ">

<p>&#8211; Queue (kolejka): Każdy komunikat trafia do jednego odbiorcy (model point-to-point). Idealne dla zadań w tle, równoważenia obciążenia i ochrony systemu przed przeciążeniem.<br />&#8211; Topics (tematy): Komunikaty mogą być dostarczone do wielu odbiorców dzięki subskrypcjom (wzorzec publish-subscribe). Doskonałe dla architektury event-driven i integracji wielu systemów.</p>

</div>
</div>
<div id="faq-question-1769434197385" class="rank-math-list-item">
<h3 class="rank-math-question "><strong>Jak działają sesje w Azure Service Bus?</strong></h3>
<div class="rank-math-answer ">

<p>Sesje umożliwiają grupowanie komunikatów na podstawie SessionID i przetwarzanie ich w określonej kolejności (sekwencyjnie) przez jednego konsumenta. Dzięki blokowaniu sesji podczas obsługi wiadomości, Azure Service Bus gwarantuje, że komunikaty w ramach jednej sesji nie będą przetwarzane równolegle. Sesje są szczególnie przydatne tam, gdzie spójność i kolejność są kluczowe, np. w procesach workflow.</p>

</div>
</div>
<div id="faq-question-1769434224557" class="rank-math-list-item">
<h3 class="rank-math-question "><strong>Co to jest Dead-Letter Queue i kiedy jest używana?</strong> </h3>
<div class="rank-math-answer ">

<p>Dead-Letter Queue to specjalna kolejka w Azure Service Bus, w której umieszczane są komunikaty, które:<br />&#8211; Nie zostały poprawnie przetworzone po określonej liczbie prób.<br />&#8211; Zawierają błędy lub nie spełniają wymagań konsumenta. Dead-Letter Queue pomaga w diagnostyce problemów i zapewnia ich późniejsze rozwiązywanie.</p>

</div>
</div>
<div id="faq-question-1769434249989" class="rank-math-list-item">
<h3 class="rank-math-question "><strong>Jakie mechanizmy bezpieczeństwa oferuje Azure Service Bus?</strong> </h3>
<div class="rank-math-answer ">

<p>Azure Service Bus oferuje:<br />&#8211; RBAC (Role-Based Access Control): Zarządzanie uprawnieniami za pomocą ról przypisanych do użytkowników, aplikacji lub zarządzanych tożsamości, bez konieczności przechowywania sekretów.<br />&#8211; SAS (Shared Access Signature): Tokeny dostępu o ograniczonym czasie ważności i zakresie uprawnień, wygodne w scenariuszach integracyjnych.<br />&#8211; AMQP 1.0: Bezpieczny i niezawodny protokół komunikacyjny o wysokiej wydajności.</p>

</div>
</div>
<div id="faq-question-1769434273643" class="rank-math-list-item">
<h3 class="rank-math-question ">Jakie wzorce projektowe wspiera Azure Service Bus?</h3>
<div class="rank-math-answer ">

<p>Azure Service Bus wspiera kilka kluczowych wzorców projektowych:<br />&#8211; Request-Response Pattern: Asynchroniczna komunikacja dwukierunkowa, oparta na kolejce żądań i odpowiedzi.<br />&#8211; Outbox Pattern: Mechanizm zapewniający spójność między zapisami w bazie danych a publikacją komunikatów. Chroni przed utratą komunikatów w przypadku awarii.<br />&#8211; Inbox Pattern: Obsługa ponownych dostarczeń komunikatów poprzez rejestrowanie MessageID w celu zapewnienia idempotentności.</p>

</div>
</div>
<div id="faq-question-1769434308990" class="rank-math-list-item">
<h3 class="rank-math-question "><strong>Jak monitorować i diagnozować Azure Service Bus w środowisku produkcyjnym?</strong> </h3>
<div class="rank-math-answer ">

<p>Do monitorowania i diagnostyki możesz użyć: <br />&#8211; Azure Monitor: Śledzenie metryk takich jak liczba aktywnych komunikatów, czas przetwarzania, długość Dead-Letter Queue i częstotliwość błędów. <br />&#8211; Application Insights: Pozwala na korelację wiadomości w kontekście całego systemu, analizę opóźnień i lokalizację problemów. <br />&#8211; Alerts i reguły powiadomień w Azure Monitor umożliwiają proaktywne wykrywanie problemów i szybkie reagowanie. </p>

</div>
</div>
<div id="faq-question-1769434337858" class="rank-math-list-item">
<h3 class="rank-math-question "><strong>Czy mogę korzystać z protokołu HTTP z Azure Service Bus?</strong></h3>
<div class="rank-math-answer ">

<p>Tak, oprócz protokołu AMQP 1.0, Azure Service Bus pozwala na korzystanie z protokołu HTTP jako alternatywy. HTTP może być stosowane w prostszych scenariuszach, gdy AMQP nie jest dostępny lub wymagany. </p>

</div>
</div>
<div id="faq-question-1769434352885" class="rank-math-list-item">
<h3 class="rank-math-question ">Jakie praktyki pomagają poprawić skalowalność systemu przy użyciu Azure Service Bus?</h3>
<div class="rank-math-answer ">

<p>Aby zwiększyć skalowalność systemu:<br />&#8211; Korzystaj z mechanizmu retry i dead-letter queue.<br />&#8211; Wykorzystuj filtry w subskrypcjach Topics dla precyzyjnego routowania zdarzeń.<br />&#8211; Używaj kolejek dla zadań w tle oraz tematów dla propagacji zdarzeń domenowych w architekturze event-driven.<br />&#8211; Grupuj komunikaty za pomocą sesji, aby kontrolować ich kolejność.</p>

</div>
</div>
<div id="faq-question-1769434379306" class="rank-math-list-item">
<h3 class="rank-math-question "><strong>Jak zoptymalizować bezpieczeństwo w Azure Service Bus?</strong></h3>
<div class="rank-math-answer ">

<p>Aby poprawić bezpieczeństwo: <br />&#8211; Używaj RBAC do zarządzania dostępem, unikając przechowywania kluczy w aplikacjach. <br />&#8211; Generuj tokeny SAS o ograniczonych uprawnieniach i krótszym czasie ważności. <br />&#8211; Chroń strumienie komunikacji za pomocą protokołu AMQP, który wspiera szyfrowanie i autoryzację. </p>

</div>
</div>
</div>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/azure-service-bus/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Gulp vs Webpack. Którego narzędzia używać w projekcie?   </title>
		<link>https://nearshore-it.eu/pl/artykuly/gulp-vs-webpack-ktorego-z-nich-uzywac-w-projekcie/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/gulp-vs-webpack-ktorego-z-nich-uzywac-w-projekcie/#respond</comments>
		
		<dc:creator><![CDATA[Maciej Woźnica]]></dc:creator>
		<pubDate>Wed, 23 Aug 2023 03:07:00 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Application development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/gulp-vs-webpack-ktorego-z-nich-uzywac-w-projekcie/</guid>

					<description><![CDATA[Webpack vs Gulp: czym się różnią?  Porównaj oba narzędzia i poznaj ich funkcjonalności, które z pewnością ułatwią ci pracę i zwiększą produktywność.]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">Przejdź do:</p>
    <ol>
                    <li><a href="#SCSS-vs-CSS-–-podstawyu002du002d">1.  SCSS vs CSS – podstawy </a></li>
                    <li><a href="#Instalacja-Webpackau002du002d">2.  Instalacja Webpacka  </a></li>
                    <li><a href="#Instalowanie-Gulpau002du002d">3.  Instalowanie Gulpa  </a></li>
                    <li><a href="#Konfiguracja-Webpackau002du002d-">4.  Konfiguracja Webpacka </a></li>
                    <li><a href="#Konfiguracja-Gulpau002du002d-">5.  Konfiguracja Gulpa </a></li>
                    <li><a href="#Obsługa-narzędzi-Gulp-vs-Webpack-–-porównanieu002du002d">6.  Obsługa narzędzi Gulp vs Webpack – porównanie </a></li>
                    <li><a href="#Które-narzędzie-wybrać:-Gulp-czy-Webpack?u002du002d-">7.  Które narzędzie wybrać: Gulp czy Webpack?</a></li>
                    <li><a href="#Gulp-vs-Webpack-–-podsumowanieu002du002d-">8.  Gulp vs Webpack – podsumowanie   </a></li>
            </ol>
</div>


<p><strong>Webpack vs Gulp</strong>&#8230; Oba te narzędzia odgrywają ważną rolę w świecie programistycznym. Wybór między nimi często na pierwszy rzut oka wydaje się trudny. Zwłaszcza na początku przygody z programowaniem. Jednak jeśli poznamy ich różnice i podobieństwa, z pewnością będzie łatwiej podjąć właściwą decyzję.</p>



<p>Bez względu na to, czy rozważasz użycie <strong>Gulpa (task runner)</strong>, <strong>Webpacka (module bundler)</strong>, czy może kombinacji obu, znajomość ich funkcjonalności z pewnością ułatwi ci pracę i zwiększy produktywność. Jeśli zatem szukasz odpowiednich narzędzi do swojego projektu, koniecznie przeczytaj ten artykuł.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image size-full">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/blog_2023.08.23_graphic_1.png" alt=" class=" class="wp-image-12066" title="Gulp vs Webpack. Którego narzędzia używać w projekcie?    7"></figure></div>


<div style="height:32px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading" id="SCSS-vs-CSS-–-podstawy--">SCSS vs CSS – podstawy &nbsp;</h2>



<p>Zanim porównam narzędzia Webpack i Gulp, przypomnijmy sobie, czym są technologie CSS i SCSS. Są one niezbędne w programowaniu na front-endzie.</p>



<p>CSS i SCSS to technologie, których na co dzień używamy do przypisywania konkretnych wyglądów do elementów (kolor, rozmiar) i rozmieszczania tych elementów na stronie. Ważne jest jednak, aby przed podjęciem decyzji o skorzystaniu z wybranej z nich wziąć pod uwagę pewne różnice.</p>



<p><strong> CSS to standardowy język arkuszy stylów, </strong>mający ugruntowaną pozycję <strong>w świecie front-endowym</strong>. W porównaniu z SCSS jego składnia wydaje się prostsza i o wiele bardziej intuicyjna. Młodsi programiści zdecydowanie stawiają na CSS, szczególnie na wczesnym etapie nauki. Reguły CSS mają na celu zdefiniowanie stylów dla określonych elementów, takich jak paragrafy, divy czy inne elementy HTML.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">/* Składnia CSS */  

h1 { color: blue; font-size: 24px; } </pre>



<p><strong>SCSS </strong>jest niczym innym jak preprocesorem CSS, to znaczy <strong>rozszerza składnię o dodatkowe funkcje i pozwala na wykorzystanie zaawansowanych technik</strong>, w tym takich jak: </p>



<ul class="wp-block-list">
<li><strong>reguły zagnieżdżania</strong> – selektory CSS można zagnieżdżać w innych, odzwierciedlając strukturę selektorów HTML.&nbsp;</li>



<li><strong>użycie zmiennych</strong> (które umożliwiają przechowywanie wartości wielokrotnego użytku w arkuszu stylów),&nbsp;</li>



<li><strong>operatory matematyczne </strong>(pozwalające na dodawanie, odejmowanie, mnożenie i dzielenie wartości w stylach), dzięki czemu jest łatwiej pisać kod i staje się on bardziej modułowy i po prostu elegancki.&nbsp;</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">/* Składnia SCSS z zagnieżdżaniem i zmiennymi */ 

$primary-color: blue; 

  

h1 {  

  kolor: $primary-color; 

  font-size: 24px; 

} </pre>



<h3 class="wp-block-heading">Kluczowe różnice między SCSS i CSS: &nbsp;</h3>



<ol start="1" class="wp-block-list">
<li><strong>Składnia:</strong> SCSS oferuje bardziej rozszerzoną składnię, co ułatwia pisanie i utrzymanie kodu. Reguły zagnieżdżania pozwalają pisać bardziej czytelny i logiczny kod. &nbsp;</li>



<li><strong>Zmienne:</strong> SCSS umożliwia definiowanie zmiennych, ułatwiając zmienianie wartości stylu w jednym miejscu i tym samym przyczyniając się do spójności w całym projekcie.&nbsp;</li>



<li><strong>Preprocesor: </strong>SCSS jest jednym z wielu preprocesorów CSS (to znaczy, że kod SCSS musi zostać skompilowany do zwykłego CSS przed wdrożeniem na stronie internetowej). &nbsp;</li>
</ol>



<p>Wybór między SCSS i CSS zależy od tego, na ile złożony jest projekt i jakie są umiejętności zespołu projektowego. W przypadku niezłożonych projektów, które nie wymagają zaawansowanych technik ostylowania, CSS może okazać się odpowiednim wyborem. Jednak w przypadku bardziej złożonych projektów, które wymagają modułowości i łatwego edytowania, <strong>SCSS pozwoli na większą elastyczność i wygodę w zarządzaniu stylami</strong>. &nbsp;</p>



<p><strong>Przeczytaj także:</strong>&nbsp;</p>



<ul class="wp-block-list">
<li><a href="https://nearshore-it.eu/pl/artykuly/testowanie-rxjs-marble-testing/" target="_blank" data-type="URL" data-id="https://nearshore-it.eu/pl/artykuly/testowanie-rxjs-marble-testing/" rel="noreferrer noopener"><strong>Marble testing. Testowanie RxJS</strong>&nbsp;&nbsp;</a></li>



<li><a href="https://nearshore-it.eu/pl/artykuly/jesli-nie-redux-to-co-zarzadzanie-stanem-aplikacji-w-react/" target="_blank" rel="noreferrer noopener"><strong>Jeśli nie Redux, to co? Zarządzanie stanem aplikacji w React</strong></a>&nbsp;<br><strong></strong>&nbsp;</li>
</ul>



<h2 class="wp-block-heading" id="Instalacja-Webpacka--">Instalacja Webpacka &nbsp;</h2>



<p>Funkcje Webpacka pozwalają przede wszystkim na zarządzanie zależnościami i porządkowanie plików. Instalacja narzędzia to naprawdę “bułka z masłem”. Zaczynamy od sprawdzenia, czy jest już zainstalowany <strong>Node Package Manager (NPM)</strong>, który moim zdaniem umożliwia najskuteczniejszą i najszybszą instalację Webpacka. Następnie otwieramy wiersz poleceń i wpisujemy: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">npm install webpack –g </pre>



<p>Z wiersza poleceń przechodzimy do katalogu z naszym projektem i wpisujemy polecenie: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">npm init </pre>



<p>Możemy tu zauważyć, że w katalogu docelowym został utworzony plik <strong>package.json</strong>. Nie pozostaje nic innego, jak tylko zainstalować Webpacka w naszym projekcie: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">npm install --save-dev webpack </pre>



<p>A teraz już możemy cieszyć się ogromnymi możliwościami narzędzia! &nbsp;</p>



<p>W dalszych krokach konfiguracja zależy od potrzeb konkretnego projektu – w punktach poniżej opiszę przykładową, krótką konfigurację. Szczegółowe wytyczne dotyczące możliwości Webpacka można znaleźć w oficjalnej dokumentacji na stronie: Webpack Documentation. &nbsp;</p>



<h2 class="wp-block-heading" id="Instalowanie-Gulpa--">Instalowanie Gulpa &nbsp;</h2>



<p>Gulp stosuje się do automatyzacji niektórych zadań, takich jak kompilacja, minifikacja plików, obrazów lub odświeżanie przeglądarki. Instalacja Gulpa jest tak samo łatwa jak w przypadku Webpacka. Upewniamy się, że mamy zainstalowany NPM. I zaczynamy od polecenia: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">npm install -g gulp </pre>



<p>Przechodzimy do naszego katalogu projektów, potem tworzymy plik package.json za pomocą polecenia: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">npm init </pre>



<p>Wystarczy teraz dodać Gulpa do naszego projektu: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">npm install ---save-dev gulp  </pre>



<p>Jak skonfigurować Webpacka? Po instalacji możemy przystąpić do tworzenia pliku gulpfile.js. Będzie on odpowiadał za konfigurację zadań dla naszego narzędzia. W dalszej części przedstawię również krótką konfigurację dla Gulpa. &nbsp;</p>



<p>Aby poznać wszystkie możliwości Gulpa,<a href="https://gulpjs.com/docs/en/getting-started/quick-start" target="_blank" data-type="URL" data-id="https://gulpjs.com/docs/en/getting-started/quick-start" rel="noreferrer noopener"> skorzystaj z dostępnej dokumentacji</a>.&nbsp;</p>



<h2 class="wp-block-heading" id="Konfiguracja-Webpacka---">Konfiguracja Webpacka  &nbsp;</h2>



<p>Jak wspomniałem wcześniej, przedstawię krótką konfigurację Webpacka. Narzędzie jest na tyle zaawansowane, że nie da rady opisać tu wszystkich jego możliwości. &nbsp;</p>



<p>Zacznijmy od dodania pliku webpack.config.js, który zawiera całą konfigurację Webpacka. &nbsp;</p>



<p>Następnie umieśćmy tam podstawową konfigurację: &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">module.exports = { 

  entry: './src/main.js', 

  output: { 

    path: __dirname + '/dist',  

    filename: 'bundle.js'  

  },  

  mode: 'production' 

};</pre>



<p>Zdefiniowaliśmy, skąd Webpack ma pobierać pliki źródłowe (<strong>entry</strong>). <strong>Output </strong>określa, gdzie powinny być umieszczone po przetworzeniu. Opcja <strong>mode </strong>określa, czy chcemy zoptymalizować kod, na przykład pod kątem produkcji. Webpack zapewnia szeroki pakiet wtyczek i loaderów, co pozwala dostosować go do naszych potrzeb. &nbsp;</p>



<h2 class="wp-block-heading" id="Konfiguracja-Gulpa---">Konfiguracja Gulpa  &nbsp;</h2>



<p>Gulp to narzędzie do automatyzacji zadań, które możemy odpowiednio dostosować w pliku <strong>gulpfile.js</strong>. W czasie konfiguracji definiujemy takie zadania, jak: minifikacja kodu, kompilacja czy odświeżanie przeglądarki po każdej zmianie w kodzie. &nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const gulp = require('gulp'); 

const uglify = require('gulp-uglify'); 


gulp.task('compress', function() {  

  return gulp.src('src/js/*.js') 

    .pipe(uglify()) 

    .pipe(gulp.dest('dist/js')); 

});</pre>



<p>To przykładowa konfiguracja mająca za zadanie skompresowanie plików JavaScript. &nbsp;</p>



<p>Zaczynamy od stworzenia nowego zadania o nazwie <strong>„Compress”</strong>. Następnie, <strong>za pomocą returngulp.src (&#8217;src/js/*.js&#8217;)</strong>, określamy pliki źródłowe do przetworzenia (w naszym przypadku będą to wszystkie pliki z rozszerzeniem .js, z katalogu src/js).&nbsp;</p>



<p>Kolejny krok to przekazanie plików źródłowych do wtyczki za pomocą <strong>pipe(uglify())</strong>, który kompresuje kod, usuwając np. zbędne spacje, komentarze, tak aby plik był możliwie jak najmniejszy.&nbsp;</p>



<p>Na koniec wskazujemy katalog do zapisywania przetworzonych plików.&nbsp;&nbsp;</p>



<h2 class="wp-block-heading" id="Obsługa-narzędzi-Gulp-vs-Webpack-–-porównanie--">Obsługa narzędzi Gulp vs Webpack – porównanie &nbsp;</h2>



<p>Jeśli miałbym porównać Webpack i Gulp, trudno wskazać jeden słuszny wybór – wszystko zależy od projektu, w którym pracujemy.&nbsp;</p>



<p>Webpack to w głównej mierze pakiet do kompilacji zasobów projektu, tak aby zyskać przejrzystość. Dzięki wtyczkom można łatwo go rozszerzyć i zyskać wachlarz zastosowań, takich jak: &nbsp;</p>



<ul class="wp-block-list">
<li><strong>Transpilacja </strong>– w przypadku JavaScript np. dostosowanie wersji ES6 do starszych przeglądarek&nbsp;</li>



<li><strong>Minifikacja kodu</strong><strong> </strong>(usuwanie niepotrzebnych znaków z kodu, aby zmniejszyć rozmiar, a tym samym poprawić czas ładowania)&nbsp;</li>



<li><strong>Zarządzanie zależnościami</strong>&nbsp;</li>
</ul>



<p>Sprawdź, jakie wtyczki są dostępne dla Gulpa: <a href="https://gulpjs.com/docs/en/getting-started/using-plugins/" target="_blank" rel="noreferrer noopener"><strong>Korzystanie z wtyczki</strong></a><strong> </strong> &nbsp;</p>



<p>Gulp to jednak także narzędzie do automatyzacji zadań, które bardzo usprawnia przepływ pracy. Moim zdaniem bardzo łatwo nauczyć się korzystać z tego narzędzia. Całkiem szybko możemy zacząć tworzyć zadania dla kompilacji plików <strong>SASS </strong>lub <strong>automatycznego odświeżania </strong>przeglądarki. Konfiguracja jest o wiele bardziej czytelna i elastyczna. &nbsp;</p>



<p>Webpack doskonale radzi sobie z zależnościami, natomiast Gulp wyróżnia się na tle innych narzędzi, jeśli chodzi o pełną automatyzację pracy (jeśli na tym ci właśnie zależy). &nbsp;</p>



<p>W skrócie: &nbsp;</p>



<ul class="wp-block-list">
<li><strong>Webpack </strong>pozwala na łączenie modułów. Ale też, tak jak Gulp, umożliwia uruchamianie wielu funkcji dotyczących zadań&nbsp;</li>
</ul>



<ul class="wp-block-list">
<li><strong>Gulp </strong>to narzędzie do automatyzowania zadań, które usprawnia przepływ pracy&nbsp;</li>
</ul>



<h2 class="wp-block-heading" id="Które-narzędzie-wybrać:-Gulp-czy-Webpack?---">Które narzędzie wybrać: Gulp czy Webpack?  &nbsp;</h2>



<p>Wybór pomiędzy nimi zależy od konkretnych potrzeb i architektury naszego projektu. To też kwestia prywatnych preferencji i doświadczenia. Jeśli łączenie i zarządzanie zależnościami są złożone i będą istotne w procesie rozwoju oprogramowania, Webpack może okazać się właściwym rozwiązaniem. Z drugiej strony, jeśli potrzebujmy prostego i czytelnego sposobu na automatyzację typowych zadań programistycznych, Gulp będzie do tego doskonały. &nbsp;</p>



<p>Pamiętaj, że nic nie stoi na przeszkodzie, aby oba narzędzia połączyć. Korzystanie z <strong>Gulpa i Webpacka jednocześnie</strong> oznacza dostęp do zalet każdego z nich. Wpłynie to pozytywnie nie tylko jakość projektu, ale też <strong>pozwoli skrócić czas potrzebny na rozwój oprogramowania</strong>. &nbsp; &nbsp;</p>



<h3 class="wp-block-heading">Użycie Webpacka zamiast Gulpa&nbsp;</h3>



<p>W połączeniu ze skryptami NPM Webpack może z powodzeniem zastąpić Gulpa. Z mojego doświadczenia wynika jednak, że lepiej łączyć narzędzia, niż ograniczać się tylko do jednego, do czego was zachęcam. Jak już wspomniałem, Webpack i Gulp to narzędzia do budowania (<strong>build tools)</strong>, które można wykorzystywać do podobnych zadań. Cechują się jednak różnymi podejściami i każde z nich ma inne mocne strony.&nbsp;&nbsp;</p>



<p>Koniec końców wybór między korzystaniem z samego Webpacka lub połączeniem go z Gulpem będzie zależeć od twojego projektu i twoich własnych preferencji programistycznych. &nbsp;</p>



<h2 class="wp-block-heading" id="Gulp-vs-Webpack-–-podsumowanie---">Gulp vs Webpack – podsumowanie  &nbsp;</h2>



<p>Mam nadzieję, że udało mi się przemycić w artykule korzyści płynące z używania Webpacka i Gulpa. Co do pytania „<strong>Webpack czy Gulp?</strong>”, tu nie ma idealnej odpowiedzi, zwłaszcza jeśli jesteś początkującym front-end developerem. Ten artykuł to tak naprawdę wprowadzenie do tych narzędzi – na każdym etapie warto wspierać się dokumentacją, wiedzą doświadczonych kolegów z projektu, a także Technical Leaderów.&nbsp; &nbsp;</p>



<p>Dokonując wyboru, najlepiej skupić się na swoich umiejętnościach, doświadczeniu i potrzebach projektowych. Nie ma uniwersalnego rozwiązania. Często ekosystem jest narzucany odgórnie. Warto więc eksperymentować z obiema technologiami, łączyć je, testować i tworzyć zoptymalizowane, wydajne środowisko. &nbsp;</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/gulp-vs-webpack-ktorego-z-nich-uzywac-w-projekcie/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Marble testing – wszystko o testowaniu RxJS</title>
		<link>https://nearshore-it.eu/pl/artykuly/testowanie-rxjs-marble-testing/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/testowanie-rxjs-marble-testing/#respond</comments>
		
		<dc:creator><![CDATA[Maciej Woźnica]]></dc:creator>
		<pubDate>Wed, 24 May 2023 10:34:41 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Application development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/testowanie-rxjs-marble-testing/</guid>

					<description><![CDATA[W tym artykule przyjrzymy się RxJS Marble testing – niezbędnemu narzędziu dla testowania biblioteki RxJS. Zbadamy zasady testowania observable (ang. observables), jak również technikę marble testing, która ułatwia tworzenie i analizowanie testów. Przeanalizujemy również korzyści płynące z tego podejścia oraz omówimy najlepsze praktyki związane z testowaniem kodu RxJS.]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">PRZEJDŹ DO:</p>
    <ol>
                    <li><a href="#RxJS-observables">1.  RxJS observables </a></li>
                    <li><a href="#Czym-jest-testowanie-R">2.  Czym jest testowanie RxJS (marble testing w RxJS)? </a></li>
                    <li><a href="#-przypadki-testowe-RxJS?u002du002d">3.  Jak pisać przypadki testowe RxJS?  </a></li>
                    <li><a href="#-jest-marble-diagram-w-RxJS?-">4.  Czym jest marble diagram w RxJS? </a></li>
                    <li><a href="#diagramy-marble-w-RxJS?-">5.   Jakie są rodzaje testów marble w RxJS? </a></li>
                    <li><a href="#ci-z-testowania-RxJS?">6.  Jakie są korzyści z testowania RxJS? </a></li>
                    <li><a href="#FAQ">7.  FAQ</a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="RxJS-observables">RxJS observables</h2>



<p>RxJS to biblioteka do tworzenia asynchronicznych strumieni danych, zarządzania nimi oraz obsługiwania zdarzeń w aplikacjach JavaScript. <strong>Kluczowym elementem RxJS są observable</strong>, które reprezentują strumienie danych emitowane w czasie.</p>



<p>Observable opierają się na wzorcu projektowym Obserwator, w którym obserwator „subskrybuje” obserwowany obiekt i oczekuje na emitowane przez niego dane. RxJS oferuje różnorodne operatory, takie jak map, filter czy merge, które pozwalają na przekształcanie, filtrowanie i łączenie strumieni danych.</p>



<p>Szerzej koncepcja biblioteki RxJS została opisana w artykule <a href="https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs" target="_blank" data-type="URL" data-id="https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs" rel="noreferrer noopener">Programowanie reaktywne z JavaScript w RxJS.</a></p>



<h2 class="wp-block-heading" id="Czym-jest-testowanie-R">Czym jest testowanie RxJS (marble testing w RxJS)?</h2>



<p>RxJS umożliwia reaktywne programowanie w JavaScript, dzięki czemu można obsługiwać asynchroniczne strumienie danych oraz manipulować nimi za pomocą różnych operacji, takich jak mapowanie, filtrowanie czy łączenie. Testowanie RxJS ma na celu zapewnienie, że kod działający na tych strumieniach jest poprawny, wolny od błędów i spełnia oczekiwania.&nbsp;</p>



<h3 class="wp-block-heading">Marble testing&nbsp;</h3>



<p>W kontekście testowania RxJS warto wspomnieć o <strong>marble testing</strong>, które jest jednym z popularnych narzędzi do testowania strumieni danych w tej bibliotece. Marble testing to nic innego jak wizualizacja strumieni danych za pomocą tzw. marble diagrams. W marble strumienie danych <strong>reprezentowane są jako ciągi znaków</strong>, gdzie każdy znak symbolizuje wartość w strumieniu lub specjalne zdarzenie, takie jak zakończenie strumienia czy wystąpienie błędu. Testowanie z użyciem diagramów marble pozwala na definiowanie oczekiwanych wyników oraz porównywanie ich z rzeczywistymi wynikami testowania, co jest szczególnie przydatne w przypadku złożonych operacji asynchronicznych.&nbsp;</p>



<h3 class="wp-block-heading">Rodzaje testów</h3>



<p>Testowanie RxJS, zwłaszcza z wykorzystaniem diagramów marble,<strong> pozwala na weryfikację poprawności działania funkcji i operatorów reaktywnych </strong>w kontekście testów jednostkowych. Testy jednostkowe koncentrują się na ocenie pojedynczych funkcji, operatorów oraz strumieni danych. Ich celem jest izolowanie poszczególnych elementów kodu i sprawdzenie, czy zachowują się zgodnie z oczekiwaniami.</p>



<p><strong>Przeczytaj także:</strong> <a href="https://nearshore-it.eu/pl/artykuly/narzedzia-automatyzacji-testow/">Narzędzia automatyzacji testów czy&nbsp;dobre praktyki? Jak przyspieszyć testowanie?</a></p>



<h3 class="wp-block-heading">Narzędzia testowania RxJS&nbsp;</h3>



<p>W celu ułatwienia testowania z użyciem diagramów marble biblioteka RxJS udostępnia takie narzędzia jak <strong>TestScheduler</strong>, który pozwala na kontrolowanie czasu w wirtualny sposób &#8211; bez wpływu na rzeczywisty czas wykonywania testów. TestScheduler umożliwia definiowanie wartości wejściowych i oczekiwanych wartości wyjściowych za pomocą marble diagrams, a następnie symuluje przepływ danych w strumieniach reaktywnych.&nbsp;</p>



<h2 class="wp-block-heading" id="-przypadki-testowe-RxJS?--">Jak pisać przypadki testowe RxJS?&nbsp;&nbsp;</h2>



<p>Pisanie przypadków testowych RxJS wymaga starannego planowania, zrozumienia kodu źródłowego oraz wykorzystania odpowiednich narzędzi do testowania. Marble testing to jedno z podejść, które pomaga w tworzeniu przejrzystych testów dla strumieni danych. Oto kilka wskazówek, jak napisać testy dla kodu opartego na bibliotece RxJS:&nbsp;</p>



<h3 class="wp-block-heading">1. Zapoznaj się z kodem źródłowym&nbsp;</h3>



<p>Przed przystąpieniem do pisania przypadków testowych dokładnie zapoznaj się z kodem źródłowym, który będzie testowany. Zrozumienie struktury kodu oraz celu poszczególnych funkcji i operatorów pozwoli na opracowanie skutecznych i kompleksowych testów.&nbsp;</p>



<h3 class="wp-block-heading">2. Wybierz odpowiedni framework do testowania&nbsp;</h3>



<p>Wybierz framework do testowania kodu JavaScript, taki jak Jasmine, Mocha czy Jest, który najlepiej odpowiada twoim potrzebom i preferencjom. Upewnij się, że wybrany framework współpracuje z RxJS i pozwala na wykorzystanie marble testing, jeśli planujesz korzystać z tego podejścia.&nbsp;</p>



<h3 class="wp-block-heading">3. Utwórz strukturę testów&nbsp;</h3>



<p>Testy jednostkowe zwykle są organizowane w blokach <strong>describe </strong>(lub podobnych, w zależności od używanego frameworka), które służą do grupowania testów dotyczących określonej funkcji, operatora lub komponentu. Wewnątrz bloków describe umieszczamy poszczególne przypadki testowe, zdefiniowane za pomocą funkcji <strong>it </strong>(lub odpowiednika w wybranym frameworku).&nbsp;</p>



<h3 class="wp-block-heading">4. Zastosuj marble testing&nbsp;</h3>



<p>Marble testing to podejście, które pozwala na wizualizację strumieni danych za pomocą tzw. marble diagrams. W marble testing strumienie danych reprezentowane są jako ciągi znaków, gdzie każdy znak symbolizuje wartość w strumieniu lub specjalne zdarzenie, takie jak zakończenie strumienia czy wystąpienie błędu.&nbsp;</p>



<p>W przypadku testowania RxJS z wykorzystaniem marble testing użyj narzędzi dostarczanych przez bibliotekę, takich jak TestScheduler. TestScheduler pozwala na kontrolowanie czasu w sposób wirtualny oraz definiowanie wartości wejściowych i oczekiwanych wartości wyjściowych za pomocą marble diagrams.&nbsp;&nbsp;</p>



<h3 class="wp-block-heading">5. Zdefiniuj przypadki testowe&nbsp;</h3>



<p>Przypadki testowe powinny być zdefiniowane w sposób czytelny i zrozumiały, opisując oczekiwane zachowanie funkcji, operatora lub strumienia danych. Wykorzystując marble testing, możesz precyzyjnie i czytelnie opisać oczekiwane zachowanie strumieni danych oraz porównać rzeczywiste wyniki z oczekiwanymi.&nbsp;</p>



<h3 class="wp-block-heading">6. Testuj różne przypadki i scenariusze&nbsp;</h3>



<p>Podczas pisania przypadków testowych warto przetestować różne scenariusze, takie jak:&nbsp;</p>



<ul class="wp-block-list">
<li>Przepływ danych o różnych wartościach&nbsp;</li>



<li>Przepływ danych z opóźnieniami lub interwałami&nbsp;</li>



<li>Zachowanie kodu w przypadku wystąpienia błędów&nbsp;</li>



<li>Zakończenie strumieni danych&nbsp;</li>



<li>Właściwe przekazywanie wartości do kolejnych operatorów&nbsp;</li>
</ul>



<ul class="wp-block-list">
<li>Spróbuj także uwzględnić przypadki brzegowe, aby upewnić się, że testowany kod jest odporny na różne sytuacje.&nbsp;</li>
</ul>



<h3 class="wp-block-heading">7. Przeglądaj i ulepszaj przypadki testowe&nbsp;</h3>



<p>Regularnie przeglądaj swoje przypadki testowe, aby upewnić się, że są aktualne i nadal spełniają swoje zadanie. Spróbuj zoptymalizować testy, eliminując powtarzalne lub zbędne fragmenty kodu, a także ułatwiając jego czytanie i zrozumienie. Dzięki temu utrzymanie i rozwój testów będą łatwiejsze w miarę wprowadzania zmian w kodzie źródłowym.&nbsp;</p>



<p>Pisanie przypadków testowych RxJS, zwłaszcza z wykorzystaniem marble testing, wymaga zrozumienia struktury kodu, wyboru odpowiedniego frameworka do testowania, tworzenia struktury testów oraz definiowania przypadków testowych, które precyzyjnie opisują oczekiwane zachowanie strumieni danych. Dzięki stosowaniu tych wskazówek będziesz w stanie tworzyć czytelne i skuteczne testy jednostkowe dla swojego kodu opartego na bibliotece RxJS.&nbsp;</p>



<h2 class="wp-block-heading" id="-jest-marble-diagram-w-RxJS?-">Czym jest marble diagram w RxJS?&nbsp;</h2>



<p>Diagramy marble to wizualne reprezentacje strumieni danych w bibliotece RxJS, które pomagają zrozumieć przepływ danych oraz interakcje między operacjami na strumieniach. Wprowadzenie diagramów marble do procesu wytwarzania oprogramowania z RxJS może poprawić czytelność kodu, ułatwić komunikację między programistami oraz przyspieszyć proces wdrażania testów.&nbsp;</p>



<h2 class="wp-block-heading" id="diagramy-marble-w-RxJS?-">Jak odczytywać diagramy marble w RxJS?&nbsp;</h2>



<p>Diagramy marble używają znaków do przedstawienia wartości emitowanych przez strumień, zakończenia strumienia, wystąpienia błędu oraz subskrypcji i jej anulowania. Oto kilka dodatkowych wskazówek, jak odczytywać diagramy:&nbsp;</p>



<p><strong>Czas:</strong> każdy myślnik (<strong>&#8211;</strong>) oznacza jednostkę czasu, zwaną również „ramką”. W testach marble długość ramki czasowej jest zdefiniowana w narzędziu TestScheduler, co pozwala na kontrolowanie upływu czasu w teście.&nbsp;</p>



<p><strong>Wartości:</strong> znaki alfanumeryczne (np.<strong> a, b, c</strong>) reprezentują wartości emitowane przez strumień danych. Wartości te są zazwyczaj zdefiniowane w obiekcie wartości przekazywanym do metody <strong>toBe()</strong>, który mapuje te znaki na rzeczywiste wartości.&nbsp;</p>



<p><strong>Subskrypcja i anulowanie subskrypcji: </strong>w Marble możemy użyć symbolu <strong>^</strong> do oznaczenia momentu, w którym subskrypcja się rozpoczyna, oraz <strong>!</strong> do oznaczenia momentu, w którym zostaje anulowana.&nbsp;</p>



<p><strong>Przykładowy diagram marble dla RxJS może wyglądać tak:</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">---a---b---c---| 
 </pre>



<p>Ten diagram reprezentuje strumień danych, który emituje trzy wartości: a, b, c, każda z nich emitowana w równych odstępach czasu. Ostatni symbol, |, oznacza, że strumień został zakończony po emisji c.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">---a---b---c---| 

        map(x => x.toUpperCase()) 

---A---B---C---| </pre>



<p>W tym przypadku mamy strumień wejściowy, który emituje wartości <strong>a</strong>, <strong>b</strong>, <strong>c</strong>. Następnie zastosowaliśmy operator map, który przekształca każdą emitowaną wartość na jej odpowiednik z dużą literą. Wynikowy strumień emituje więc wartości <strong>A</strong>, <strong>B</strong>, <strong>C</strong>.&nbsp;</p>



<p>Diagramy marble mogą być znacznie bardziej skomplikowane, z wieloma operatorami i zdarzeniami. Kluczowe jest zrozumienie podstawowej notacji, aby móc interpretować i tworzyć takie diagramy.&nbsp;</p>



<h2 class="wp-block-heading">Jakie są rodzaje testów marble w RxJS?</h2>



<p>Testy marble w RxJS dzielimy na dwa główne rodzaje: testy jednostkowe i testy integracyjne.</p>



<h3 class="wp-block-heading">Testy jednostkowe</h3>



<p>Skupiają się na izolowaniu i testowaniu indywidualnych komponentów, operatorów lub funkcji. Marble testing jest bardzo przydatne w testach jednostkowych, ponieważ pozwala na precyzyjne sprawdzanie sekwencji zdarzeń oraz efektów poszczególnych operatorów na strumieniach danych. W testach jednostkowych korzystamy z TestScheduler, który pozwala kontrolować upływ czasu oraz weryfikować oczekiwane wyniki testów.</p>



<h3 class="wp-block-heading">Testy integracyjne</h3>



<p>Testują interakcje między różnymi komponentami, operatorami lub funkcjami w systemie. Marble testing może być również używane w testach integracyjnych, aby zbadać, jak różne części kodu współpracują ze sobą. W testach integracyjnych sprawdzamy, czy przepływ danych między różnymi komponentami jest zgodny z oczekiwaniami. Testowanie marble w kontekście testów integracyjnych jest bardziej złożone niż w przypadku testów jednostkowych, ale może dostarczyć cenne informacje na temat zachowania systemu jako całości.&nbsp;</p>



<p>W testowaniu z wykorzystaniem diagramów marble&nbsp; istotne jest również zrozumienie operatorów „hot” i „cold”. W kontekście strumieni danych operator „hot” to taki, który emituje wartości niezależnie od tego, czy istnieje obecnie jakakolwiek subskrypcja. Z kolei operator „cold” zaczyna emitować wartości dopiero po subskrypcji. W testach marble operator „cold” jest zazwyczaj reprezentowany przez strumienie oznaczone jako <strong>source</strong>. Najlepiej będzie spojrzeć na przykład:&nbsp;&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import { TestScheduler } from 'rxjs/testing'; 

import { of, Subject } from 'rxjs'; 

import { map, takeUntil } from 'rxjs/operators'; 
 

it('should demonstrate hot and cold observables', () => { 

  const testScheduler = new TestScheduler((actual, expected) => { 

    expect(actual).toEqual(expected); 

  }); 

 

  testScheduler.run(({ cold, hot, expectObservable }) => { 

    const sourceCold$ = cold(' --a--b--c--|'); 

    const sourceHot$ = hot('  --d--e--f--|'); 

    const stop$ = cold('      -----s--|'); 

    const expectedMarble = '  --x--y--(z|)'; 

 

    const resultCold$ = sourceCold$.pipe( 

      takeUntil(stop$), 

      map((value) => value.toUpperCase()) 

    ); 

    const resultHot$ = sourceHot$.pipe( 

      takeUntil(stop$), 

      map((value) => value.toUpperCase()) 

    ); 

    expectObservable(resultCold$).toBe(expectedMarble, { 

      x: 'A', 

      y: 'B', 

      z: 'C' 

    }); 

    expectObservable(resultHot$).toBe(expectedMarble, { 

      x: 'D', 

      y: 'E', 

      z: 'F' 

    }); 

  }); 

}); </pre>



<p>W powyższym przykładzie widzimy dwa strumienie danych: „cold” i „hot&#8221;. Strumień „cold” zaczyna emitować wartości tylko po subskrypcji, podczas gdy strumień „hot” emituje wartości niezależnie od subskrypcji. W teście używamy operatora „<strong>takeUntil</strong>” do zakończenia obserwacji strumieni danych w odpowiednim momencie.&nbsp;</p>



<p>Podsumowując, marble diagrams w RxJS są niezwykle pomocne w zrozumieniu przepływu danych oraz zachowań poszczególnych operatorów w strumieniach danych. Testowanie marble ułatwia tworzenie testów jednostkowych oraz integracyjnych, które są niezbędne dla poprawnego działania aplikacji opartej na RxJS. Wiedza na temat diagramów marble oraz umiejętność pisania skutecznych testów marble są ważnymi kompetencjami każdego programisty korzystającego z biblioteki RxJS.&nbsp;</p>



<p>W przypadku pracy z marble warto pamiętać o kilku dodatkowych zasadach i wskazówkach, które mogą ułatwić proces testowania:</p>



<ul class="wp-block-list">
<li><strong>Konwencje nazewnictwa:</strong> kiedy tworzysz strumienie danych za pomocą diagramów marble, warto utrzymywać konwencje nazewnictwa i używać nazw związanych z funkcjonalnością strumieni. Dzięki temu możemy łatwo zrozumieć, jakie dane przepływają przez strumienie, co ułatwia analizowanie wyników testów.&nbsp;</li>
</ul>



<ul class="wp-block-list">
<li><strong>Korzystanie z helperów: </strong>w wielu przypadkach testowania marble możemy skorzystać z funkcji pomocniczych dostarczanych przez bibliotekę RxJS, takich jak <strong>TestScheduler</strong>,<strong> hot</strong>,<strong> cold</strong>,<strong> time</strong>,<strong> expectObservable </strong>i<strong> expectSubscriptions</strong>. Te funkcje ułatwiają tworzenie diagramów marble oraz zarządzanie nimi i testowanie przepływu danych między różnymi strumieniami.&nbsp;</li>



<li><strong>Weryfikacja wyników testów:</strong> podczas pisania testów marble warto zwracać uwagę na wyniki testów i błędy zgłaszane przez narzędzia do testowania, takie jak Jasmine lub Mocha. Dzięki temu możemy szybko zidentyfikować i naprawić błędy w naszym kodzie.&nbsp;</li>



<li><strong>Dokładność testów:</strong> testowanie marble pozwala na precyzyjne śledzenie sekwencji zdarzeń w strumieniach danych. Jednak ważne jest, aby pamiętać, że testowanie marble nie zastępuje innych rodzajów testowania, takich jak testy jednostkowe czy integracyjne. Warto korzystać z różnych technik testowania w zależności od kontekstu i potrzeb aplikacji.&nbsp;</li>



<li><strong>Praktyka: </strong>testowanie marble może być na początku trudne do zrozumienia, ale z biegiem czasu i nabieranym doświadczeniem staje się coraz łatwiejsze. Praca z różnymi przykładami i scenariuszami pomoże zrozumieć, jak najlepiej wykorzystać diagramy marble w testach RxJS.&nbsp;</li>
</ul>



<p>Używając marble w RxJS, można skutecznie testować strumienie danych oraz interakcje między operacjami. Diagramy marble ułatwiają zrozumienie przepływu danych oraz oczekiwanych wyników testów, co prowadzi do budowania bardziej niezawodnych i wydajnych aplikacji. Praktyka i doświadczenie są kluczowe w opanowaniu testowania marble, ale korzyści płynące z jego zastosowania są nieocenione dla każdego programisty Front-End.</p>



<p><strong>Przeczytaj także:</strong> <a href="https://nearshore-it.eu/pl/artykuly/testy-regresji/" data-type="URL" data-id="https://nearshore-it.eu/pl/artykuly/testy-regresji/" target="_blank" rel="noreferrer noopener">Test regresji – strata czasu czy&nbsp;must have w&nbsp;projekcie?</a></p>



<h2 class="wp-block-heading" id="ci-z-testowania-RxJS?">Jakie są korzyści z testowania RxJS?</h2>



<ul class="wp-block-list">
<li><strong>Działanie kodu zgodne z oczekiwaniami</strong> – testowanie kodu RxJS jest niezwykle ważne, gdyż pozwala na zwiększenie pewności, że kod działa zgodnie z oczekiwaniami. Dzięki testom programiści mogą być pewni, że ich aplikacje rzeczywiście spełniają założone wymagania biznesowe, co przekłada się na mniejsze ryzyko wystąpienia błędów czy niezgodności.&nbsp;</li>



<li><strong>Wykrywanie błędów</strong> – jednocześnie testowanie ułatwia wykrywanie błędów, ponieważ sprawdza indywidualne funkcje, operatory oraz interakcje między nimi. Dzięki temu możliwe jest szybsze zidentyfikowanie i naprawienie problemów w kodzie. To wpływa również na skrócenie czasu debugowania, gdyż testy pomagają programistom szybko zlokalizować źródło błędu.&nbsp;</li>



<li><strong>Łatwiejsze wprowadzanie zmian</strong> – testy RxJS wspierają także wprowadzanie zmian w kodzie, gdyż automatycznie sprawdzają funkcjonalność po każdej modyfikacji. Dzięki temu programista może szybciej wykryć i naprawić ewentualne problemy wynikające z wprowadzonych zmian. Ponadto testy ułatwiają refaktoryzację, gdyż programista może być pewny, że jego zmiany nie wprowadzą regresji.&nbsp;</li>



<li><strong>Dokumentacja kodu </strong>–<strong> </strong>warto również zauważyć, że testy RxJS często służą jako dokumentacja dla kodu, dostarczając informacji o tym, jak korzystać z poszczególnych funkcji i jakie są ich oczekiwane wyniki. Taka dokumentacja jest nieoceniona dla innych programistów, którzy chcą zrozumieć czyjś kod i wiedzieć, jak go używać.&nbsp;</li>
</ul>



<ul class="wp-block-list">
<li><strong>Większe zaufanie do oprogramowania</strong> – wreszcie testowanie zwiększa zaufanie do kodu zarówno wśród programistów, jak i interesariuszy projektu. Wszyscy mogą być pewni, że aplikacja rzeczywiście działa poprawnie i spełnia wymagania. Testy są kluczowe dla utrzymania wysokiej jakości aplikacji opartych na strumieniach danych i reaktywnym programowaniu.&nbsp;</li>



<li><strong>Lepszy kod</strong> – w efekcie testowanie kodu RxJS przyczynia się do lepszej jakości kodu, szybszego wykrywania i naprawiania błędów, łatwiejszego wprowadzania zmian oraz wzrostu zaufania do kodu. Jako ekspert od RxJS, zdecydowanie polecam stosowanie testów we wszelkich projektach opartych na tej bibliotece.&nbsp;</li>
</ul>



<h2 class="wp-block-heading" id="FAQ">FAQ</h2>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1684867289692" class="rank-math-list-item">
<h3 class="rank-math-question ">Czym cechują się frameworki testowe RxJS i jak wybrać najlepszy? </h3>
<div class="rank-math-answer ">

<p>Frameworki testowe RxJS to narzędzia służące do tworzenia, organizowania i wykonywania testów dla kodu opartego na RxJS. Wybór najlepszego frameworka zależy od potrzeb projektu i preferencji zespołu. Przy wyborze frameworka testowego dla RxJS warto zwrócić uwagę na następujące aspekty: <br /> <br /><strong>Obsługa Marble Testing:</strong> ważne jest, aby wybrać framework, który obsługuje testy marble, gdyż są one kluczowe w testowaniu reaktywnych strumieni danych. <br /><strong>Integracja z innymi narzędziami:</strong> sprawdź, jak dobrze framework integruje się z innymi narzędziami używanymi w projekcie, takimi jak bundlery, środowiska CI/CD czy lintery.  <br /><strong>Łatwość użycia:</strong> framework testowy powinien być łatwy w konfiguracji i użyciu. <br /><strong>Popularność i wsparcie społeczności:</strong> popularne frameworki testowe mają większe szanse na aktywny rozwój i wsparcie społeczności. <br /><strong>Dokumentacja: </strong>dobra dokumentacja jest kluczowa dla szybkiego wprowadzenia frameworka testowego do projektu oraz dla zrozumienia jego możliwości. <br /><strong>Wydajność:</strong> wydajność frameworka testowego wpływa na czas wykonywania testów. <br /><strong>Elastyczność i możliwości rozszerzenia:</strong> wybrany framework powinien oferować elastyczność w konfiguracji oraz możliwość rozszerzenia o dodatkowe narzędzia lub funkcje. <br />Przykłady popularnych frameworków testowych wspierających RxJS to Jasmine, Jest i Mocha. Każdy z nich oferuje różne funkcje i zalety, dlatego warto dokładnie przeanalizować ich możliwości przed podjęciem decyzji o wyborze. </p>

</div>
</div>
<div id="faq-question-1684867306736" class="rank-math-list-item">
<h3 class="rank-math-question ">Jak wdrożyć testowanie RxJS? </h3>
<div class="rank-math-answer ">

<p>Aby wdrożyć testowanie RxJS w projekcie, na początek należy wybrać odpowiedni framework testowy, który wspiera testy marble, tak jak Jasmine, Jest lub Mocha. Wybór powinien zależeć od potrzeb projektu i preferencji zespołu. Następnie przystąp do instalacji i konfiguracji wybranego frameworka testowego, używając menedżera pakietów, takiego jak npm lub yarn, i postępując zgodnie z instrukcjami dostarczanymi przez dokumentację frameworka. </p>
<p>Jeśli wybrany framework testowy nie obsługuje testów marble bezpośrednio, zainstaluj dodatkowe narzędzia, takie jak rxjs-marbles dla Mochy czy jest-marbles dla Jesta. Teraz możesz zacząć pisanie testów jednostkowych dla komponentów, usług, operatorów i strumieni opartych na RxJS. Wykorzystaj testy marble do reprezentowania i testowania reaktywnych strumieni danych. Upewnij się, że testujesz kluczowe scenariusze, zarówno pozytywne, jak i negatywne, aby sprawdzić poprawność działania kodu. <br />Dobrze jest umieścić testy w dedykowanych plikach lub folderach, aby łatwo można było je znaleźć i zarządzać nimi. Przyjętym standardem jest umieszczanie testów w folderze <strong>__tests__</strong> lub w plikach z rozszerzeniem <strong>.spec.ts </strong>lub <strong>.test.ts.</strong> Aby uruchomić testy, użyj narzędzi dostarczonych przez framework testowy, zarówno lokalnie, jak i na serwerze CI/CD. W zależności od frameworka możesz wykorzystać polecenia CLI, takie jak <strong>npm test</strong>, <strong>yarn test</strong> czy <strong>ng test.</strong> </p>
<p>Monitoruj wyniki testów, analizuj błędy i naprawiaj problemy w kodzie. Użyj narzędzi do generowania raportów i statystyk, aby ocenić jakość kodu oraz śledzić postęp w testowaniu. W miarę jak projekt się rozwija, aktualizuj i utrzymuj testy, pisząc nowe testy dla nowych funkcji oraz aktualizując istniejące testy w przypadku zmian w kodzie. Dzięki temu utrzymanie wysokiej jakości kodu będzie znacznie łatwiejsze  </p>

</div>
</div>
<div id="faq-question-1684867333157" class="rank-math-list-item">
<h3 class="rank-math-question ">Jakie są typowe błędy testowania RxJS? </h3>
<div class="rank-math-answer ">

<p>Jednym z takich błędów jest nieuwzględnienie zasady asynchroniczności przy testowaniu. W przypadku testowania strumieni danych ważne jest, aby pamiętać o użyciu odpowiednich technik testowania asynchronicznego, takich jak testy marble, czy wykorzystywanie funkcji <strong>fakeAsync</strong> i <strong>tick</strong> dostarczanych przez Angulara. </p>
<p>Inny typowy błąd polega na niewłaściwym zarządzaniu subskrypcjami. Jeśli subskrypcje nie zostaną anulowane po zakończeniu testów, może to prowadzić do wycieków pamięci i fałszywie pozytywnych wyników testów. Warto zwrócić uwagę na to, aby odpowiednio zarządzać subskrypcjami, zwłaszcza w przypadku testowania komponentów czy usług. </p>
<p>Częstym błędem jest również niewłaściwe użycie operatorów RxJS, które może prowadzić do nieoczekiwanych rezultatów. Szczególnie ważne jest zrozumienie różnicy między operatorem <strong>switchMap</strong> a <strong>mergeMap </strong>oraz innymi operatorami, które mają wpływ na zachowanie strumieni danych. </p>
<p>Nieodpowiednie testowanie błędów może prowadzić do fałszywego poczucia bezpieczeństwa. Warto zwrócić uwagę na testowanie obsługi błędów, zwłaszcza w przypadku asynchronicznych operacji, takich jak żądania HTTP. W takich przypadkach warto użyć odpowiednich operatorów do obsługi błędów, takich jak <strong>catchError</strong> i <strong>retry</strong>. </p>
<p>Niedokładne testowanie warunków brzegowych i skrajnych scenariuszy może prowadzić do niewykrycia problemów. Dlatego warto dążyć do pełnego pokrycia testami, a także badać różne kombinacje danych wejściowych, które mogą wpłynąć na działanie strumieni danych. Testowanie tych przypadków może ujawnić potencjalne problemy, których można nie zauważyć podczas testowania tylko typowych scenariuszy. </p>
<p>Ostatnim błędem, ale nie mniej ważnym, jest niewłaściwe stosowanie operatorów cold i hot podczas testowania marble. Warto zrozumieć różnice między tymi operatorami oraz wiedzieć, kiedy stosować jeden, a kiedy drugi, aby uzyskać wiarygodne wyniki testów. </p>

</div>
</div>
<div id="faq-question-1684867388576" class="rank-math-list-item">
<h3 class="rank-math-question ">Jakie są wzorce projektowe testowania RxJS? </h3>
<div class="rank-math-answer ">

<p>Wzorce projektowe testowania RxJS to sprawdzone techniki stosowane w testowaniu aplikacji opartych na tej bibliotece. Kluczowym elementem jest wdrożenie testów marble, które umożliwiają wizualizację i testowanie strumieni danych, a także analizę interakcji między nimi. Dzięki stosowaniu takich wzorców testy asynchroniczne staną się bardziej efektywne, a izolacja testowanych części aplikacji od zewnętrznych zależności pozwoli na kontrolowanie zachowań i przetestowanie różnych scenariuszy. </p>

</div>
</div>
<div id="faq-question-1684867400504" class="rank-math-list-item">
<h3 class="rank-math-question ">Jakie są najlepsze praktyki testowania? </h3>
<div class="rank-math-answer ">

<p>W odniesieniu do najlepszych praktyk testowania w kontekście biblioteki RxJS warto skupić się na podejściach i technikach, które czynią testy efektywnymi, wydajnymi i łatwymi w utrzymaniu. Testowanie asynchroniczne, w tym <strong>async</strong>, <strong>fakeAsync</strong> czy <strong>testy marble</strong>, pozwala na przetestowanie różnych scenariuszy związanych z asynchronicznymi operacjami. Kluczowe jest również testowanie obsługi błędów, aby sprawdzić, czy są one prawidłowo obsługiwane w strumieniach danych. Ważne jest, aby testować warunki brzegowe i skrajne scenariusze, co pozwala na wykrycie potencjalnych problemów, które mogą umknąć podczas testowania tylko typowych scenariuszy. Monitorowanie poziomu pokrycia testami oraz dbanie o dobrą organizację testów, umieszczanie ich w dedykowanych plikach lub folderach, ułatwia zarządzanie kodem i utrzymanie jego przejrzystości. </p>

</div>
</div>
</div>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/testowanie-rxjs-marble-testing/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Clean Architecture</title>
		<link>https://nearshore-it.eu/pl/artykuly/clean-architecture/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/clean-architecture/#respond</comments>
		
		<dc:creator><![CDATA[Artur Szymanski]]></dc:creator>
		<pubDate>Wed, 15 Mar 2023 12:20:00 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Application development]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/clean-architecture/</guid>

					<description><![CDATA[Stałe i spójne podejście w pisaniu kodu jest ważnym elementem realizacji projektów. Będzie ono miało wpływ na całość prowadzonych prac oraz czas realizacji. W dzisiejszym artykule chcę się przyjrzeć podejściu Clean Architecture. Jaka jest główna idea tworzenia architektury typu Clean Architecture i w jakich sytuacjach się ona sprawdzi? Postaram się również omówić i przedstawić jej główne zalety.]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">Przejdź do:</p>
    <ol>
                    <li><a href="#Wybor-architektury">1.  Wybór architektury</a></li>
                    <li><a href="#Architektura-a-dlug-technologiczny">2.  Architektura a dług technologiczny</a></li>
                    <li><a href="#Czym-jest-Clean-Architecture">3.  Czym jest Clean Architecture</a></li>
                    <li><a href="#Idea-Clean-Architecture">4.  Idea Clean Architecture</a></li>
                    <li><a href="#Clean-Architecture-wzorce-projektowe">5.  Clean Architecture – wzorce projektowe</a></li>
                    <li><a href="#Application">6.  Application</a></li>
                    <li><a href="#Presentation">7.  Presentation</a></li>
                    <li><a href="#Domain">8.  Domain</a></li>
                    <li><a href="#Data">9.  Data</a></li>
                    <li><a href="#Wady-Clean-Architecture">10.  Wady Clean Architecture</a></li>
                    <li><a href="#Zalety-Clean-Architecture">11.  Zalety Clean Architecture</a></li>
                    <li><a href="#W-jakich-projektach-stosowac-Clean-Architecture">12.  W jakich projektach stosować Clean Architecture?</a></li>
                    <li><a href="#Podsumowanie">13.  Podsumowanie</a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="Wybor-architektury">Wybór architektury</h2>



<p>Rozpoczynając nowy projekt, developerzy chcą bardzo szybko zakończyć pierwsze zadanie, pomijając wagę przygotowania projektu. To&nbsp;błąd! Przecież to&nbsp;właśnie początkowy etap tworzenia nowej aplikacji jest najważniejszy. Pozwala on wypracować spójne, stałe podejście dla pozostałych developerów biorących udział w&nbsp;projekcie.</p>



<p><strong>Czytaj także:&nbsp;</strong><a href="https://www.jcommerce.eu/jpro/articles/neo4j-zaproszenie-do-grafowych-baz-danych" target="_blank" rel="noopener noreferrer"><strong>Neo4j – zaproszenie do&nbsp;grafowych baz danych</strong></a></p>



<h2 class="wp-block-heading" id="Architektura-a-dlug-technologiczny">Architektura a dług technologiczny</h2>



<p>Kolejnym błędem popełnianym przez&nbsp;developerów jest doprowadzenie do&nbsp;długu technologicznego.&nbsp;<strong>Prawdą jest, że&nbsp;często tworzymy coś szybko, wydawać by&nbsp;się mogło sensownie… Jednak ze&nbsp;względu na&nbsp;różne czynniki zaciągamy coraz większy dług technologiczny.</strong>&nbsp;W&nbsp;pracy projektowej nie&nbsp;warto iść na&nbsp;skróty. Pośpiech i&nbsp;zaniedbanie to&nbsp;najczęstsze przyczyny nawarstwiania się długu technologicznego w&nbsp;projekcie.</p>



<p>Pół biedy, jeśli zaciągamy dług, który&nbsp;potrafimy później „spłacić”, czyli w&nbsp;odpowiednim czasie dokonać poprawek. Gorzej, jeśli zaciągamy dług przekraczający nasze umiejętności lub wychodzący poza ramy czasowe projektu. Niemożliwy do&nbsp;spłacenia dług technologiczny doprowadzić może do&nbsp;czegoś, co wszyscy dobrze znamy. Idealnie obrazuje to&nbsp;grafika poniżej.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/12.17_Clean-Architecture.png" alt="Clean Archotecture - dług technologiczny na przykładzie długu publicznego Polski" class="wp-image-25149" title="Clean Architecture 8"></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Aby uniknąć tego problemu, warto użyć jednego z wielu dostępnych wzorców tworzenia architektury projektowej. Moim faworytem, a zarazem najczęściej używanym przeze mnie podejściem, jest Clean Architecture.</p>



<h2 class="wp-block-heading" id="Czym-jest-Clean-Architecture">Czym jest Clean Architecture</h2>



<p>Clean Architecture to podejście do programowania aplikacji, które zakłada wydzielenie czterech głównych modułów funkcjonalnych w projekcie. Moduły te to:</p>



<ul class="wp-block-list">
<li><strong>Application,</strong></li>



<li><strong>Presentation,</strong></li>



<li><strong>Domain,</strong></li>



<li><strong>Data.</strong></li>
</ul>



<p>W dalszej części omówię szczegółowo każdą z nich. Na początek kilka słów o głównej idei podejścia Clean Architecture.</p>



<h2 class="wp-block-heading" id="Idea-Clean-Architecture">Idea Clean Architecture</h2>



<p>Robert C. Martin (Uncle Bob) w książce &#8222;Clean Architecture&#8221; definiuje cel architektury jako wspieranie cyklu życia systemu. Dalej za autorem: dobra architektura sprawia, że ​​system jest łatwy do zrozumienia, łatwy w rozwoju, łatwy w utrzymaniu i łatwy do wdrożenia. Ostatecznym celem jest zminimalizowanie kosztów eksploatacji systemu i maksymalizacja produktywności programistów.</p>



<p>Tworząc podejście Clean Architecture Robert C. Martin, dążył do&nbsp;stworzenia struktury projektu z&nbsp;wyraźnie oddzieloną odpowiedzialnością poszczególnych warstw.&nbsp;<strong>Założenie było następujące: każda z&nbsp;warstw ma wykonywać jedno zadanie i&nbsp;ma być łatwa do&nbsp;wyizolowania od&nbsp;reszty. Inne założenie to&nbsp;możliwość współdzielenia jednego kodu między wieloma środowiskami.</strong>&nbsp;Miałoby się to&nbsp;odbywać poprzez wyciągnięcie dwóch głównych modułów niezależnych od&nbsp;technologii użytej do&nbsp;tworzenia aplikacji: Presentation oraz&nbsp;Domain i&nbsp;współdzielenie w&nbsp;innych środowiskach, dopisując jedynie warstwy Application oraz&nbsp;Data. Warstwy te są ściśle powiązane ze&nbsp;środowiskiem, na&nbsp;którym&nbsp;uruchamiamy projekt. Dobrym przykładem może być napisanie logiki biznesowej raz i&nbsp;współdzielenie jej przez&nbsp;aplikacje mobilne na&nbsp;iOS i&nbsp;Android, ale&nbsp;również przez&nbsp;aplikacje webowe i&nbsp;desktopowe.</p>



<h2 class="wp-block-heading" id="Clean-Architecture-wzorce-projektowe">Clean Architecture – wzorce projektowe</h2>



<p>Moduł prezentacji może zostać zaimplementowany za pomocą wielu popularnych wzorców projektowych: Model View ViewModel (MVVM), Model View Presenter (MVP), Model View Intent (MVI), Model View Controller (MVC) czy też wiele innych. Każdy programista ma własne preferencje, jeśli chodzi o wybór wzorca. Mimo iż każdy z nich ma wady i zalety, na potrzeby opisu tej architektury skupimy się na podejściu MVP. Jest to podejście, które osobiście preferuję.</p>



<h2 class="wp-block-heading" id="Application">Application</h2>



<p>Warstwa aplikacji jest najmocniej połączona z technologią, w której używamy podejścia Clean Architecture. Zapewnia ona całą wizualną część projektu oraz reaguje na zadania powierzane jej przez warstwę prezentacji. Warstwa ta decyduje, w jaki sposób wyświetlane będą dane dostarczane przez część prezentacyjną. Zawiera ona logikę wyświetlania oraz informuje warstwę prezentacji o wszelkich akcjach wykonanych przez użytkownika. Obsługuje ona też mechanizm utrzymywania stanu Presentera oraz przygotowuje wszelkie niezbędne zależności do jego poprawnego działania.</p>



<h2 class="wp-block-heading" id="Presentation">Presentation</h2>



<p>Presenter steruje całą aplikacją, jak i poszczególnymi ekranami, reaguje on również na poszczególne akcje wykonane przez użytkownika w części wizualnej. To również tu zapada decyzja, w jaki sposób obsłużyć dane zadania czy też jaką część aplikacji kolejno pokazać użytkownikowi. UseCase’y, opisane dalej, są jedynym sposobem komunikacji tego modułu z pozostałymi. Służy np. do wykonania logiki biznesowej lub też pobrania określonych danych. W podejściu MVP każdy Presenter ma interfejs do komunikacji z widokiem, komunikacja ta pozwala jedynie na zlecanie zadań widokowi, ale nie umożliwia ona żądania czegoś w zamian. Mówiąc prościej, Presenter wykonuje funkcje na interfejsie widoku, ale funkcje te nie mogą mieć typu zwracanego.</p>



<h2 class="wp-block-heading" id="Domain">Domain</h2>



<p>Domain to moduł zawierający całą logikę biznesową. Składa się on z wielu składowych:</p>



<h3 class="wp-block-heading">UseCase</h3>



<p>Najważniejsza, widoczna na zewnątrz składowa, wykorzystywana przez warstwę prezentacji. UseCase’y są odwzorowaniem realnych wymagań biznesowych i zapewniają logice prezentacji dostęp do operacji na danych (pobierania, zmiany, nasłuchiwania zmian). Umożliwiają również wykonywanie logiki biznesowej: obliczeń czy manipulacji na danych. Warto wspomnieć, iż są one jedyną możliwością komunikacji między warstwą prezentacji a warstwami domeny. Dane transportowane są przez modele przechowywane również w tej warstwie. UseCase’y dostęp do danych otrzymują za pośrednictwem DataSource’ów poprzez udostępniony przez nie interfejs. Innym rodzajem wykorzystywanych przez nie zależności są klasy z warstwy Logic opisane dalej.</p>



<h3 class="wp-block-heading">Model</h3>



<p>To zbiór w pewien logiczny sposób zebranych danych, wykorzystywanych przez logikę biznesową. Model ten nie musi być identyczny jak model z warstwy data. Może on np. łączyć kilka modeli data w zależności od potrzeb i zastosowania.</p>



<h3 class="wp-block-heading">Logic</h3>



<p>Miejsce w strukturze, które służy do przechowywania wydzielonych klas z rozbudowaną logiką biznesową. Miejsce te umożliwia unikanie rozbudowanych UseCase’ów.</p>



<h3 class="wp-block-heading">DataSource</h3>



<p>Najważniejszym zadaniem DataSource’ów jest decydowanie, skąd będą pobierane lub gdzie zapisywane będą dane. Właśnie one za pomocą interfejsów mają dostęp do wszystkich źródeł danych, które wystawia moduł Data. Oprócz danych w środku znajdziemy również Mappery umożliwiające tłumaczenie danych z warstwy Data na modele biznesowe wykorzystywane później. DataSource’y są jedynym połączeniem między modułem Data a resztą logiki biznesowej i to one wystawiają dalej interfejsy dające dostęp do dostosowanych danych dla UseCase’ów.</p>



<h3 class="wp-block-heading">Mappery</h3>



<p>Mappery w architekturze Clean Architecture dbają o spójność danych dostarczanych przez warstwę data. To właśnie tu odbywa się sprawdzenie, czy wszystkie niezbędne dane zostały dostarczone, tak aby logika biznesowa mogła w pełni działać. Mappery często łączą kilka obiektów z warstwy data z różnych źródeł, tworząc jeden, który ma wszystkie potrzebne dla logiki biznesowej dane.</p>



<h2 class="wp-block-heading" id="Data">Data</h2>



<p>Moduł, który dostarcza dostęp do wszelkiego typu źródeł danych oraz modeli, które te dane odwzorowują. Dostęp do metod udostępnianych przez ten moduł możliwy jest jedynie dzięki wykorzystaniu interfejsów, które ten moduł udostępnia. Jest on również drugim modułem mającym największą zależność od platformy, na której wykorzystywana jest Clean Architecture.</p>



<h3 class="wp-block-heading">Data transfer object</h3>



<p>Data transfer object (w skrócie DTO) jest to model służący do dwustronnego przesyłania danych. Modele takie wykorzystywane są tylko w warstwie Data i w zależności od tego, czy dane te wysyłamy, czy też pobieramy, są one tłumaczone na modele biznesowe lub z nich za pomocą Mapperów.</p>



<h3 class="wp-block-heading">Data</h3>



<p>Data to miejsce pobierania i zapisywania danych wykorzystywanych w pozostałych częściach aplikacji. Przykładowe źródła danych to: Bluetooth, Internet, Shared Preferences, bazy danych, pliki, GPS, kamera, żyroskop czy system. Dostęp do takich danych odbywa się przez interfejs. Pozwala to na łatwe podmienianie danego źródła. Zamiana takiego źródła odbywa się poprzez podanie różnych obiektów implementujących ten interfejs. Zastępowanie źródeł danych najczęściej wykorzystywane jest np. do obsługi różnych typów serwerów czy też podpięcia mockowych danych.</p>



<h2 class="wp-block-heading" id="Wady-Clean-Architecture">Wady Clean Architecture</h2>



<ul class="wp-block-list">
<li><strong>Czasochłonność.</strong> Zaimplementowanie tak złożonej architektury wymaga dodatkowego czasu. Z mojego doświadczenia wynika, że pisanie kodu w podejściu Clean Architecture wymaga około 10% więcej czasu niż tworzenie aplikacji bez żadnej specjalnej architektury.</li>



<li><strong>Potrzebna jest wiedza.</strong> W ten typ podejścia wpisany jest utrudniony próg wejścia dla osób, które nie miały wcześniej wiedzy na temat tej struktury.</li>



<li><strong>Duża ilość małych klas i interfejsów.</strong> Jedni uważają to za wadę, inni z kolei za zaletę. Uczciwie będzie, gdy stwierdzimy, że w każdej opinii jest ziarno prawdy. Moja opinia jest taka, że to niewątpliwa zaleta – osoby mające inne zdanie uważają, że duża ilość plików jest trudna w zarządzaniu, a zmiany w nich poczynione – mało czytelne.</li>
</ul>



<h2 class="wp-block-heading" id="Zalety-Clean-Architecture">Zalety Clean Architecture</h2>



<ul class="wp-block-list">
<li><strong>Łatwiejsze utrzymanie.</strong> Clean Architecture znacząco ułatwia utrzymanie projektu. Naprawianie błędów w tym podejściu jest bardzo proste, a ich lokalizowanie – szybsze.</li>



<li><strong>Lepsze zarządzanie zmianą.</strong> Podejście przyśpiesza wprowadzanie zmian w projekcie. Dzięki małym klasom z wydzielonymi odpowiedzialnościami bardzo łatwo modyfikować kod pod kątem nowych wymagań czy też dodawać nowe funkcjonalności bez obawy o konsekwencje w pozostałych częściach projektu.</li>



<li><strong>Duża ilość małych klas i interfejsów.</strong> Jak już pisałem, tu zdania są podzielone. Ja uważam, że jest to zaleta z tego względu, że dzięki wielu małym klasom z wydzielonymi funkcjonalnościami kod daje się łatwo pokryć testami.</li>
</ul>



<h2 class="wp-block-heading" id="W-jakich-projektach-stosowac-Clean-Architecture">W jakich projektach stosować Clean Architecture?</h2>



<p><strong>Moim zdaniem Clean Architecture świetnie spełnia swoje zadanie w przypadku średnich i&nbsp; dużych projektów.</strong> Złożoność podejścia w przypadku małych projektów może skutkować większym nakładem dodatkowych prac. Czy to znaczy jednak, że nie powinniśmy stosować wtedy Clean Architecture? Warto pamiętać, że małe projekty w naturalny sposób szybko się rozwijają. Podjęcie decyzji o stosowaniu podejścia CA nawet w mniejszych projektach jest moim zdaniem uzasadnione. Pozwala to uniknąć sytuacji zaciągania długu technologicznego, o którym pisałem. Szczególnie, gdy narzut czasowy jest nieduży.</p>



<h2 class="wp-block-heading" id="Podsumowanie">Podsumowanie</h2>



<p>Nawiązując do konceptu współdzielenia dwóch modułów między wieloma technologiami, uważam to za świetny pomysł i coraz bliższy realizacji. Do tej pory było to trudne w uzyskaniu, jednak dzięki upowszechnieniu języka programowania, jakim jest Kotlin już niedługo możemy mieć pierwsze projekty w pełni wykorzystujące te założenia. Mam nadzieję, że udało mi się przybliżyć główne założenia idei Clean Architecture i zachęcić do stosowania jej w projektach. Przemyślany wybór architektury pozwoli uniknąć długu technologicznego, a ten typ architektury – choć wymaga wiedzy i przeznaczenia więcej czasu na implementację, bez wątpienia sprawdza się długofalowo zarówno w większych, jak i mniejszych projektach.</p>



<p><strong>Przeczytaj także:</strong></p>



<ul class="wp-block-list">
<li><a href="https://jcommerce.catdesignapp.com/test-driven-development-na-co-dzien" target="_blank" rel="noopener">Test-Driven Development na co dzień</a></li>



<li><a href="https://jcommerce.catdesignapp.com/service-mesh-ale-komu-to-potrzebne" target="_blank" rel="noopener">Service mesh, ale komu to potrzebne?</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/clean-architecture/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Higher-Order Observable Mapping w RxJS</title>
		<link>https://nearshore-it.eu/pl/artykuly/operator-wyzszego-rzedu-rxjs/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/operator-wyzszego-rzedu-rxjs/#respond</comments>
		
		<dc:creator><![CDATA[Maciej Woźnica]]></dc:creator>
		<pubDate>Wed, 01 Mar 2023 12:26:00 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Application development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/operator-wyzszego-rzedu-rxjs/</guid>

					<description><![CDATA[Biblioteka RxJs, którą szczegółowo opisałem w poprzednim artykule, oferuje szereg możliwości pracy z danymi, reagowania na zachowania użytkownika czy wszelkie inne zdarzenia zachodzące w aplikacji. W skrócie: RxJs to biblioteka ułatwiająca wykorzystanie konceptu programowania reaktywnego. Jednym z takich ułatwień są operatory wyższego rzędu. Z tego artykułu dowiesz się, czym jest Higher-Order Observable Mapping w RxjS, jakie są rodzaje operatorów i jak mogą ci pomóc w pracy ze strumieniowymi danymi. Zaczynajmy!]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title"></p>
    <ol>
                    <li><a href="#Observable">1.  Observable oraz strumień danych </a></li>
                    <li><a href="#Operatory-w-RxJS">2.  Operatory w RxJS</a></li>
                    <li><a href="#Switchmap">3.  SwitchMap</a></li>
                    <li><a href="#Mergemap">4.  MergeMap</a></li>
                    <li><a href="#Contactmap">5.  ContactMap</a></li>
                    <li><a href="#exhaustmap">6.  ExhaustMap</a></li>
                    <li><a href="#faq">7.  FAQ</a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="Observable">Observable oraz strumień danych</h2>



<p>Jednymi z najważniejszych elementów biblioteki RxJS są Observable oraz strumienie danych.</p>



<p>Oba te pojęcia są podobne, jednak występują między nimi subtelne różnice:</p>



<figure class="wp-block-table aligncenter is-style-stripes"><table><thead><tr><th><strong>Strumienie danych</strong>&nbsp;&nbsp;</th><th><strong>Observable</strong>&nbsp;</th></tr></thead><tbody><tr><td>Strumienie danych są reprezentowane przez klasę Observable w bibliotece RxJS.&nbsp;</td><td>Observable może też reprezentować pojedyncze wartości, a nie tylko strumienie.&nbsp;</td></tr><tr><td>Mają węższy zakres i pozwalają na manipulacje na danych i kontrolowanie ich w ograniczony sposób.&nbsp;</td><td>Ma szerszy zakres zastosowań niż strumienie danych, ponieważ pozwalają na manipulowanie strumieniami i kontrolowanie ich w bardziej zaawansowany sposób.&nbsp;&nbsp;&nbsp;</td></tr><tr><td>Strumienie danych nie pozwalają na multipleksowanie, łączenie, filtrowanie i mapowanie danych.&nbsp;</td><td>Observable pozwala na wykonanie pewnych operacji, takich jak multipleksowanie, łączenie, filtrowanie i mapowanie, co pozwala na bardziej zaawansowaną pracę z danymi.&nbsp;&nbsp;&nbsp;</td></tr><tr><td>Strumienie danych to sekwencje wartości, które są emitowane przez źródło.&nbsp;</td><td>Observable to obiekt, który służy do zarządzania strumieniem danych.&nbsp;&nbsp;&nbsp;</td></tr><tr><td>Nie można za ich pomocą kontrolować czasu przepływu wartości czy sterować błędami.&nbsp;</td><td>Ma dodatkowe cechy pozwalające np. na kontrolowanie czasu przepływu wartości lub sterowanie błędami. &nbsp;&nbsp;</td></tr><tr><td>Strumienie danych są sekwencjami wartości emitowanymi przez źródło.&nbsp;</td><td>Observable to obiekt, który zarządza strumieniami danych i pozwala na manipulowanie nimi.&nbsp;</td></tr></tbody></table></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Podsumowując, Observable mają szerszy zakres zastosowań niż strumienie danych i mają dodatkowe funkcje, pozwalające na kontrolowanie czasu przepływu wartości i sterowanie błędami.</p>



<h2 class="wp-block-heading" id="Operatory-w-RxJS">Operatory w RxJS</h2>



<p>Prawdziwą potęgę biblioteki RxJS stanowią operatory. Operatory pozwalają przekształcać, filtrować, łączyć strumienie danych i zarządzać nimi. RxJS dostarcza szereg operatorów, takich jak: map, filter, reduce, debounceTime, distinctUntilChanged itp., które pozwalają na przetwarzanie danych w strumieniach. Wybór odpowiedniego operatora jest ważny, gdyż źle dobrany operator może wpłynąć na funkcjonowanie systemu. Niżej omawiam najważniejsze z nich.</p>



<p><strong>Przeczytaj także:</strong> <a href="https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs/">Programowanie reaktywne w JavaScript z RxJS</a></p>



<p><strong>Higher-Order Observable Mapping</strong></p>



<p>Biblioteka RxJS zawiera szczególny typ operatorów, tzw. <strong>higher-order operators</strong>, czyli operatory wyższego rzędu, które pozwalają na złożone manipulowanie strumieniami danych. Higher-order operators to operatory, które zawierają w argumentach inne operatory lub Observable i zwracają nowe Observable mające zastosowanie do pierwotnego strumienia danych.</p>



<p>Istnienie higher-order operators w bibliotece RxJS jest uzasadnione z kilku powodów:</p>



<ul class="wp-block-list">
<li><strong>Zapewniają one prostsze i bardziej czytelne sposoby manipulowania strumieniami danych. </strong>Dzięki nim można złożyć wiele operacji na strumieniu w jeden łańcuch, co ułatwia czytanie i zrozumienie kodu.</li>



<li><strong>Umożliwiają bardziej elastyczne manipulowanie strumieniami danych. </strong>Wiele higher-order operators pozwala na dynamiczne tworzenie nowych strumieni danych w zależności od zdarzeń zachodzących w pierwotnym strumieniu. Dzięki temu można łatwo dostosować przetwarzanie danych do zmieniających się wymagań.</li>



<li><strong>Higher-order operators pozwalają na wielokrotne wykorzystanie kodu.</strong> Wiele operacji na strumieniach danych jest podobnych i można je zastosować w wielu miejscach w aplikacji. Higher-order operators ułatwiają użycie tych samych operacji w różnych częściach kodu, co pozwala na uniknięcie powtórzeń.</li>
</ul>



<p>Podsumowując, higher-order operators w bibliotece RxJS pozwalają na bardziej elastyczne, czytelne i wielokrotne wykorzystanie kodu do manipulowania strumieniami danych. Dzięki nim programiści mogą złożyć wiele operacji na strumieniu w jeden łańcuch, co ułatwia zarządzanie danymi w aplikacji.</p>



<p>RxJS udostępnia nam cztery operatory wyższego rzędu:</p>



<h3 class="wp-block-heading" id="Switchmap">SwitchMap</h3>



<p><strong>Operator switchMap emituje wartości wewnętrznego Observable, ale każda nowa wartość emitowana przez strumień źródłowy powoduje anulowanie poprzedniego wewnętrznego Observable i utworzenie nowego.</strong> Wewnętrzny Observable zwrócony z funkcji mapującej jest zastępowany nowym wewnętrznym Observable, co oznacza, że jeśli źródłowy strumień emituje wartości z częstotliwością wyższą niż wewnętrzny Observable, operator switchMap przerywa działanie i zastępuje poprzedni wewnętrzny Observable. SwitchMap możemy zastosować w przypadku, gdy chcemy odwołać wcześniejsze żądania i wysłać tylko najnowsze żądanie, np. dotyczące filtrowania wyników wyszukiwania.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import { fromEvent } from 'rxjs'; 

import { switchMap } from 'rxjs/operators'; 

 

Pobieranie danych z serwera 

function fetchData(keyword: string) { 

  return fetch(`https://api.github.com/search/repositories?q=${keyword}`).then(res => res.json()); 

} 
 </pre>



<p>Strumień wejściowy z danymi z pola tekstowego</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const input$ = fromEvent(document.querySelector('input'), 'input'); </pre>



<p>Operator switchMap kończy subskrypcję poprzedniego strumienia i zwraca tylko strumień wyjściowy ostatniego wyemitowanego strumienia</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const result$ = input$.pipe( 

  switchMap(event => fetchData(event.target.value)) 

); </pre>



<p>Subskrypcja strumienia wyjściowego</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">result$.subscribe( 

  data => console.log(data), 

  err => console.error(err), 

  () => console.log('Complete') 

); </pre>



<p>W tym przykładzie operator switchMap przekształca każdą wartość strumienia wejściowego (event z pola tekstowego) na strumień wyjściowy, który pobiera dane z serwera GitHub API na podstawie frazy wyszukiwania. Dzięki temu, kiedy użytkownik wprowadza nową frazę, operator switchMap anuluje subskrypcję poprzedniego strumienia wyjściowego i zwraca tylko wynik dla ostatniej frazy.</p>



<h3 class="wp-block-heading" id="Mergemap">MergeMap</h3>



<p>Operator mergeMap<strong> przetwarza wszystkie wartości w strumieniu źródłowym jednocześnie, emitując wartości wewnętrzne Observable</strong>. Operator tworzy wiele wewnętrznych Observables, co oznacza, że wynikowy strumień wyjściowy może emitować wartości w dowolnej kolejności. Przykładowym zastosowaniem operatora mergeMap może być równoległe pobieranie danych z wielu źródeł.</p>



<p>Operator mergeMap jest szczególnie przydatny w sytuacjach, gdy potrzebujemy wykonać operację asynchroniczną dla każdego elementu strumienia wejściowego i uzyskać strumień wyjściowy składający się z wyników tych operacji.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import { from, Observable } from 'rxjs'; 

import { mergeMap } from 'rxjs/operators'; </pre>



<p>Definicja funkcji zwracającej strumień asynchroniczny</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">function makeHttpRequest(id: number): Observable {

return fetch(https://jsonplaceholder.typicode.com/posts/${id}).then(res => res.json());

}</pre>



<p>Strumień wejściowy z listą identyfikatorów</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const ids$ = from([1, 2, 3, 4, 5]); 

 </pre>



<p>Operator mergeMap przekształca każdy element strumienia wejściowego na strumień wyjściowy</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const posts$ = ids$.pipe( 

  mergeMap(id => makeHttpRequest(id)) 

); </pre>



<p>Subskrypcja strumienia wyjściowego</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">posts$.subscribe( 

  post => console.log(post), 

  err => console.error(err), 

  () => console.log('Complete') 

); </pre>



<p>W tym przykładzie operator mergeMap przekształca każdy element strumienia wejściowego (identyfikator posta) na strumień wyjściowy reprezentujący wynik asynchronicznej operacji pobierania danych z serwera dla danego posta. W efekcie otrzymujemy strumień wyjściowy składający się z pobranych postów, a nie z identyfikatorów.</p>



<h3 class="wp-block-heading" id="Contactmap">ContactMap</h3>



<p>Operator concatMap emituje wartości wewnętrznego Observable w kolejności, w jakiej są one dostarczane. Operator nie tworzy wielu wewnętrznych Observables, dopóki poprzedni Observable nie zakończy działania. W przypadku, gdy w strumieniu źródłowym pojawi się kolejna wartość, zanim zakończy działanie poprzedni wewnętrzny Observable. Operator concatMap umieszcza wartości kolejnego wewnętrznego Observable w kolejce i przetwarza je dopiero po zakończeniu poprzedniego Observable.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import { of } from 'rxjs'; 

import { concatMap, delay } from 'rxjs/operators'; </pre>



<p>Strumień wejściowy z liczbami</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const source$ = of(1, 2, 3, 4, 5); </pre>



<p>Operator concatMap przekształca każdy element strumienia wejściowego na nowy strumień wyjściowy z opóźnieniem w zależności od wartości elementu</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const example$ = source$.pipe( 

  concatMap(value => of(`Delayed by: ${value * 1000}ms`).pipe(delay(value * 1000))) 

); </pre>



<p>Subskrypcja strumienia wyjściowego</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">example$.subscribe(console.log); </pre>



<p>W powyższym przykładzie concatMap przekształca każdą wartość strumienia wejściowego (1, 2, 3, 4, 5) na strumień wyjściowy, który zostaje opóźniony o wartość elementu w sekundach i zwrócony w kolejności ich pojawiania się w źródłowym strumieniu. Dzięki temu pierwszy element (1) zostanie zwrócony po jednej sekundzie, drugi element (2) po dwóch sekundach itd.</p>



<h3 class="wp-block-heading" id="exhaustmap">ExhaustMap</h3>



<p>Operator exhaustMap<strong> przekształca każdy element strumienia wejściowego (źródłowego) na nowy strumień i ignoruje wszystkie kolejne elementy, zanim zakończy działanie strumień wyjściowy.</strong></p>



<p>ExhaustMap jest przydatny, gdy jest nam potrzebne, żeby w danym czasie był emitowany tylko jeden strumień wyjściowy. W przypadku, gdy pojawiają się nowe elementy w strumieniu wejściowym przed zakończeniem strumienia wyjściowego, są one ignorowane aż do zakończenia działania poprzedniego strumienia wyjściowego.</p>



<p>Przykładowym zastosowaniem operatora exhaustMap może być ograniczenie liczby żądań sieciowych w sytuacji, gdy w aplikacji użytkownik kliknie wiele razy na przycisk, ale zwrócone zostanie tylko jedno zapytanie.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""> 

import { interval } from 'rxjs'; 

import { exhaustMap, take } from 'rxjs/operators'; </pre>



<p>Strumień wejściowy z wartościami</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const source$ = interval(1000).pipe(take(4)); </pre>



<p>Operator exhaustMap przekształca każdą wartość strumienia wejściowego na nowy strumień wyjściowy, który zostaje zwrócony dopiero po zakończeniu działania jego poprzednika.&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">const example$ = source$.pipe( 

  exhaustMap(value => interval(500).pipe(take(3))) 

); </pre>



<p>Subskrypcja strumienia wyjściowego&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">example$.subscribe(console.log); </pre>



<p>Powyższy przykład obrazuje sytuacje, gdy operator exhaustMap przekształca każdą wartość strumienia wejściowego (0, 1, 2, 3) na strumień wyjściowy emitujący wartości z opóźnieniem 0,5 sekundy. Każdy kolejny strumień wyjściowy zostanie zignorowany, dopóki poprzedni nie zostanie zakończony, dlatego drugi strumień wyjściowy z wartościami (0, 1, 2) nie zostanie wyemitowany, ponieważ pierwszy strumień z wartościami (0, 1, 2) nadal jest w trakcie emisji.</p>



<h2 class="wp-block-heading">Podsumowując:</h2>



<ul class="wp-block-list">
<li><strong>exhaustMap</strong> ignoruje nowe zdarzenia, jeśli obecny strumień wciąż trwa. Jeśli w trakcie trwania strumienia wejściowego operator otrzyma kolejne zdarzenie, to zostanie ono pominięte, aż do momentu, gdy strumień wejściowy się zakończy.</li>



<li><strong>mergeMap</strong> przetwarza wszystkie wartości w strumieniu źródłowym jednocześnie, emitując wartości wewnętrznych Observables.</li>



<li><strong>concatMap</strong> emituje wartości wewnętrznego Observable w kolejności, w jakiej są one emitowane.</li>



<li><strong>switchMap</strong> emituje wartości wewnętrznego Observable, ale zastępuje poprzedni wewnętrzny Observable nowym, gdy źródłowy strumień emituje nowe wartości.</li>
</ul>



<h2 class="wp-block-heading" id="faq">FAQ:&nbsp;&nbsp;</h2>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-1682427320388" class="rank-math-list-item">
<h3 class="rank-math-question ">Czym jest RxJS?</h3>
<div class="rank-math-answer ">

<p>RxJS to biblioteka programistyczna napisana w języku JavaScript, która implementuje wzorzec programowania reaktywnego, oparty na strumieniach danych. RxJSu <strong>umożliwia programowanie reaktywne w języku JavaScript</strong>.</p>
<p>Biblioteka RxJS zapewnia programistom szereg narzędzi i operacji do tworzenia, przetwarzania i obsługi strumieni danych. Umożliwia tworzenie i łączenie strumieni z różnych źródeł, np. interakcji użytkownika czy zapytań HTTP. RxJS dostarcza także wiele operatorów, które umożliwiają transformowanie, filtrowanie i łączenie strumieni danych.</p>
<p>RxJS ma wiele zastosowań, takich jak obsługa zdarzeń interakcji użytkownika w aplikacjach internetowych, tworzenie strumieni danych z serwera lub integracja z frameworkami frontendowymi, takimi jak Angular czy React.</p>

</div>
</div>
<div id="faq-question-1682427349404" class="rank-math-list-item">
<h3 class="rank-math-question ">Czym jest strumień danych w programowaniu reaktywnym?</h3>
<div class="rank-math-answer ">

<p>W programowaniu reaktywnym strumień danych to sekwencja zdarzeń, która może mieć miejsce w czasie i być przetwarzana asynchronicznie. Może to być na przykład strumień zdarzeń z interfejsu użytkownika, strumień danych z sieci, pliku, bazy danych lub innego źródła. <strong>Strumienie danych są kluczowym elementem w programowaniu reaktywnym, ponieważ pozwalają na przetwarzanie zdarzeń i reagowanie na nie w czasie rzeczywistym, w miarę ich pojawiania się</strong>. Strumienie mogą mieć zero lub wiele wartości. W bibliotece RxJS operatorami są funkcje, które pozwalają na pracę z asynchronicznymi strumieniami danych. Dzięki wykorzystaniu operatorów i strumieni danych programowanie reaktywne umożliwia tworzenie skalowalnych, elastycznych i wydajnych aplikacji. Szerzej zostało to opisane w artykule „Programowanie reaktywne w JS z RxJS”.</p>

</div>
</div>
<div id="faq-question-1682427351812" class="rank-math-list-item">
<h3 class="rank-math-question ">Jak efektywniej wykorzystać bibliotekę RxJS?</h3>
<div class="rank-math-answer ">

<p>&#8211; <strong>Używaj Observables zamiast Promises </strong>– Observables są bardziej elastyczne niż Promises i pozwalają na łatwe operowanie na strumieniu danych.<br />&#8211; <strong>Unikaj nadmiernego korzystania z operatorów </strong>– operatorów w RxJS jest wiele i bardzo łatwo jest przesadzić z ich wykorzystaniem. Zawsze należy zastanowić się, czy dany operator jest potrzebny i czy faktycznie przyczynia się do poprawy czytelności i wydajności kodu.<br />&#8211; <strong>Unikaj jednoczesnego korzystania z wielu strumieniu</strong> – w RxJS bardzo łatwo jest stworzyć wiele strumieni danych, co może prowadzić do problemów z wydajnością aplikacji. Zawsze należy zastanowić się, czy rzeczywiście potrzebujemy tak wielu strumieni i czy nie da się ich połączyć w jeden.<br />&#8211; <strong>Zwracaj uwagę na pamięć</strong> – w RxJS strumienie danych są połączone z pamięcią, więc warto zwracać uwagę na to, czy nie tworzymy niepotrzebnie dużych strumieni, które mogą powodować problemy z wydajnością.<br />&#8211; <strong>Korzystaj z operatorów wysokiego rzędu</strong> – operator wysokiego rzędu w RxJS pozwala na tworzenie bardziej skomplikowanych strumieni danych. Ich umiejętne wykorzystanie może znacznie ułatwić pracę i poprawić czytelność kodu.<br />&#8211; <strong>Testuj kod </strong>– RxJS jest bardzo potężną biblioteką, ale wymaga ona również więcej uwagi podczas testowania. Zawsze warto pamiętać o testowaniu swojego kodu.</p>
<p>Powyższe porady są ogólne i zależą od konkretnych wymagań projektu. W każdym przypadku warto jednak pamiętać o zachowaniu czytelności i przejrzystości kodu, a także o testowaniu swojego rozwiązania.</p>

</div>
</div>
<div id="faq-question-1682427440915" class="rank-math-list-item">
<h3 class="rank-math-question ">Czym jest typ obiektu? Dlaczego musisz go zasubskrybować, aby otrzymać dane?</h3>
<div class="rank-math-answer ">

<p>Typ obiektu w RxJS to abstrakcyjny typ danych, który reprezentuje strumień wartości emitowanych przez źródło. Typ ten definiuje interfejs do tworzenia, przetwarzania i subskrybowania strumieni danych w programowaniu reaktywnym.</p>
<p>Ważną cechą strumienia danych w RxJS jest to, że <strong>nie emituje on danych do subskrybenta automatycznie</strong>. W przeciwieństwie do klasycznych zapytań HTTP, które zwracają wynik tylko raz, strumienie danych mogą emitować wartości wielokrotnie w czasie. Aby otrzymać wartości emitowane przez strumień danych, musisz zasubskrybować go, czyli utworzyć subskrypcję. Subskrypcja reprezentuje połączenie pomiędzy subskrybentem a źródłem danych, które umożliwia odbieranie wartości emitowanych przez strumień.</p>
<p>Subskrypcja umożliwia również zarządzanie cyklem życia strumienia danych. Możesz anulować subskrypcję, jeśli nie potrzebujesz już otrzymywać wartości z danego strumienia. Możesz również wykonywać różne operacje na strumieniu, takie jak transformacje, filtrowanie lub łączenie z innymi strumieniami, poprzez użycie operatorów RxJS.</p>
<p>Podsumowując, <strong>subskrypcja jest niezbędna, aby otrzymać wartości emitowane przez strumień danych w RxJS</strong>. Dzięki temu, że subskrypcje umożliwiają zarządzanie cyklem życia strumienia, można w łatwy sposób manipulować przepływem danych w programowaniu reaktywnym.</p>

</div>
</div>
</div>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/operator-wyzszego-rzedu-rxjs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Wprowadzenie do funkcjonalnego programowania reaktywnego w JavaScript z RxJS</title>
		<link>https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs/#respond</comments>
		
		<dc:creator><![CDATA[Maciej Woźnica]]></dc:creator>
		<pubDate>Wed, 26 Oct 2022 10:38:33 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Application development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/programowanie-reaktywne-w-js-z-rxjs/</guid>

					<description><![CDATA[Współczesne aplikacje internetowe wymagają od programistów coraz wydajniejszych rozwiązań. Czasy, kiedy główną funkcjonalnością strony WWW było wyświetlenie statycznego tekstu, obsługa kliknięcia czy wysłanie wiadomości za pomocą formularza, mamy dawno za sobą.  
Bardzo często jako twórcy aplikacji musimy mierzyć się z coraz większymi wymaganiami użytkowników oraz rosnącą ilością danych, co znacząco wpływa na wydajność naszych witryn. Z pomocą przychodzi programowanie reaktywne – w artykule omawiam jego możliwości na przykładzie biblioteki RxJS.]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">Przejdź do:</p>
    <ol>
                    <li><a href="#Wyzwania-współczesnych-aplikacji-internetowych">1.  Wyzwania współczesnych aplikacji internetowych</a></li>
                    <li><a href="#Czym-jest-programowanie-reaktywne?">2.  Czym jest programowanie reaktywne? </a></li>
                    <li><a href="#Strumienie-danych">3.  Strumienie danych </a></li>
                    <li><a href="#Co-to-jest-observable?">4.  Co to jest observable? </a></li>
                    <li><a href="#Observable-vs-promise-w-JavaScript">5.  Observable vs promise w JavaScript </a></li>
                    <li><a href="#Hot-vs-cold-observables">6.  Hot vs cold observables </a></li>
                    <li><a href="#Tworzenie-observable">7.  Tworzenie observable </a></li>
                    <li><a href="#Subskrybcje">8.  Subskrybcje</a></li>
                    <li><a href="#Observer">9.  Observer</a></li>
                    <li><a href="#RxJS-–-zalety">10.  RxJS – zalety </a></li>
                    <li><a href="#RxJS-–-wady">11.  RxJS – wady </a></li>
                    <li><a href="#Podsumowanie">12.  Podsumowanie </a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="Wyzwania-współczesnych-aplikacji-internetowych">Wyzwania współczesnych aplikacji internetowych</h2>



<p>Tworząc nowoczesne i wydajne aplikacje internetowe, mierzymy się z wieloma wyzwaniami, o czym wspominał m.in. Paweł Adamowicz w swoim materiale <a href="https://nearshore-it.eu/pl/artykuly/ngrx" target="_blank" data-type="URL" data-id="https://nearshore-it.eu/pl/artykuly/ngrx" rel="noreferrer noopener">Zarządzanie stanem aplikacji frontendowej za pomocą NgRx</a>. Jako programiści powinniśmy między innymi brać pod uwagę to, że nie można blokować użytkownika i kazać mu czekać, aż nasza witryna obsłuży kilka zdarzeń. Co zatem zrobić w momencie, kiedy aplikacja jednocześnie musi uruchomić animację, załadować loader czy zareagować na działanie użytkownika? Jak obsłużyć te wszystkie sytuacje naraz? Tutaj z pomocą przychodzi nam paradygmat programowania reaktywnego wraz z <strong>biblioteką</strong> <strong>RxJS</strong>.</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_2022.10.26_graphic_1-1.png" alt="RXJS - programowanie reaktywne" class="wp-image-68374" title="Wprowadzenie do funkcjonalnego programowania reaktywnego w JavaScript z RxJS 9"></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading" id="Czym-jest-programowanie-reaktywne?">Czym jest programowanie reaktywne?</h2>



<p>Programowanie reaktywne to paradygmat służący do pisania kodu opierającego się na asynchronicznych strumieniach danych.</p>



<p>Jest to sposób tworzenia aplikacji, które reagują na zachodzące zmiany, w przeciwieństwie do typowego, imperatywnego sposobu pisania oprogramowania, w którym jawnie tworzymy instrukcję krok po kroku, aby te zmiany obsłużyć.</p>



<p>Brzmi to dość skomplikowanie i faktycznie takie podejście wymaga zmiany sposobu myślenia. Jednak istnieją rozwiązania, które zdecydowanie ułatwią zmianę podejścia na reaktywne – w przypadku JavaScript jest nim właśnie biblioteka RxJS.</p>



<h2 class="wp-block-heading" id="Strumienie-danych">Strumienie danych</h2>



<p>Strumień to sekwencja danych uporządkowanych w czasie. Strumienie danych mogą być tworzone z obiektów, zmiennych, struktur danych, za pomocą zdarzeń (kliknięć), odpowiedzi żądań HTTP itd.</p>



<p>Na swojej osi czasu strumień może również emitować error (gdy wystąpi nieoczekiwane zdarzenie powodujące zakończenie strumienia) lub status completed, gdy strumień wyemitował wszystkie dane. Możemy przechwycić te metody (<strong>error i complete</strong>) i wykonać na nich odpowiednie dla nas operacje, o czym więcej piszę w dalszej części.</p>



<p><strong>Przeczytaj także:</strong> <a href="https://nearshore-it.eu/pl/artykuly/angular-zrobmy-swoja-progressive-web-application">Angular – zróbmy swoją PWA</a>.</p>



<h2 class="wp-block-heading" id="Co-to-jest-observable?">Co to jest observable?</h2>



<p>RxJS udostępnia nam obiekt observable, który wykorzystuje wzorzec projektowy – <strong>obserwator</strong>.</p>



<p>Możemy to zilustrować na przykładzie subskrybcji do newslettera. Zapewne nieraz zdarzyło ci się kliknąć przycisk „subskrybuj”, czy to na YouTube, czy np. jakimś blogu. W momencie kiedy pojawi się nowy artykuł lub inny materiał, dostajesz od razu powiadomienie o pojawieniu się nowych zasobów. W każdym momencie możesz także zrezygnować z subskrypcji.</p>



<p>Tak samo działają observable i strumienie.</p>



<ul class="wp-block-list">
<li>Klikając przycisk subscribe, stajesz się obserwatorem danych zasobów,</li>



<li>observable jako obiekt obserwowany serwuje nam strumień danych z nowościami,</li>



<li>subskrypcja do strumienia zapewnia nam metodę „subscribe”,</li>



<li>możemy również wybrać, które dane są dla nas wartościowe jako nowości.</li>
</ul>



<h2 class="wp-block-heading" id="Observable-vs-promise-w-JavaScript">Observable vs promise w JavaScript</h2>



<p>Observable to nic innego jak strumień z wartościami (absolutnie dowolnego typu). Ale zaraz, zaraz… Po co nam ten cały observable, skoro mamy już promise w JavaScript? Observable daje nam dużo większe możliwości, poniżej krótkie porównanie:</p>



<h3 class="wp-block-heading">Promise</h3>



<ul class="wp-block-list">
<li>za każdym razem jest asynchroniczny,&nbsp;</li>



<li>jest „eager” – przetwarzanie rozpoczyna się natychmiastowo po jego zdefiniowaniu,&nbsp;</li>



<li>może zwracać tylko jedną wartość,&nbsp;</li>



<li>nie posiada operatorów,&nbsp;</li>



<li>nie może być anulowany.</li>
</ul>



<h3 class="wp-block-heading">Observable</h3>



<ul class="wp-block-list">
<li>może być zarówno synchroniczny, jak i asynchroniczny,</li>



<li>jest „lazy” – będzie wykonany nie w momencie zdefiniowania strumienia, ale w momencie, w którym utworzona zostanie subskrypcja,</li>



<li>zwraca jedną lub wiele wartości,</li>



<li>do dyspozycji mamy całą gamę operatorów,</li>



<li>możemy go anulować w dowolnym momencie,</li>



<li>daje nam więcej możliwości przy obsłudze błędów (m.in. operator retry()).</li>
</ul>



<h2 class="wp-block-heading" id="Hot-vs-cold-observables">Hot vs cold observables</h2>



<p>Observable dzielimy na hot i cold.</p>



<h3 class="wp-block-heading">Cold observables:</h3>



<ul class="wp-block-list">
<li>emitowanie wartości zaczyna się w momencie pojawienia się pierwszego subskrybenta (gdy pojawi się pierwszy subscribe() – o tym w dalszej części artykułu),</li>



<li>dla każdego nowego subskrybenta zwracają nowe wartości,</li>



<li>przykładem może być np. serwis do pobierania danych z backendu, gdzie żeby wykonać zapytanie, musimy użyć subscribe.</li>
</ul>



<h3 class="wp-block-heading">Hot observables:</h3>



<ul class="wp-block-list">
<li>wysyłają wartości pomimo braku subskrybenta,</li>



<li>dzielą te same dane pomiędzy wszystkich subskrybentów,</li>



<li>przykład: observable stworzony z eventu click.</li>
</ul>



<h2 class="wp-block-heading" id="Tworzenie-observable">Tworzenie observable</h2>



<p>Istnieje wiele sposobów na stworzenie observable. Często spotykamy się z tworzeniem ich z innych struktur danych – tutaj z pomocą przychodzą nam operatory <strong>of </strong>lub <strong>from</strong>. Dla RxJS nie jest również problemem stworzenie jednego observable z kilku innych. Poniżej kilka przykładów.</p>



<p>Operator <strong>from </strong>przyjmuje tylko jeden argument, po którym można iterować (np. tablice, elementy tablicopodobne, weźmy za przykład tablicę obiektów).</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""> 

import { from, Observable } from 'rxjs'; 

  

const to ReadBooks = [  

{  bookId: 1, title: The psychology of money', author: 'Morgan Housel' 

publicationYear: 2020 }, 

{  bookId: 2, title: 'The subtle art of not giving a f*ck', author: 'Mark Manson', 			publicationYear: 2016 }, 

{ bookId: 3, title: How to talk to anyone', author: 'Leil Lowndes', publicationYear: 1999 }, 

{ bookId: 3, title: 'Invent and wander', author: Jeff Bezos', publicationYear: 2020 }, 

  

];  

  

let source2$ = from(toReadBooks); 

source2$.subscribe(book => console.log(book.title)); </pre>



<p><strong>W ten sposób nasza tablica obiektów zamieniła się w observable. Proste, prawda?</strong></p>



<p>A co w sytuacji, gdy mamy kilka strumieni, a potrzebujemy jednego observable? Żaden problem! RxJS udostępnia kilka operatorów, które nam w tym pomogą. Jednym z nich jest <strong>concat</strong>.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import { concat, from, Observable, of } from 'rxjs'; 

  

const toReadBooks = [ 

  

  

{  bookId: 1, title: The psychology of money', author: 'Morgan Housel'  

publicationYear: 2020 },  

{  bookId: 2, title: 'The subtle art of not giving a f*ck', author: 'Mark Manson', 			publicationYear: 2016 },  

{ bookId: 3, title: How to talk to anyone', author: 'Leil Lowndes', publicationYear: 1999 },  

{ bookId: 3, title: 'Invent and wander', author: Jeff Bezos', publicationYear: 2020 }, 

  

];  

  

let source1$ = of('hello', 10, true, toReadBooks[0].title); 

source1$.subscribe(value => console.log(value)); 

  

let source2$ = from(toReadBooks); 

source2$.subscribe(book => console.log(book.title)); 

  

// combine the 2 sources  

concat(source1$, source2$) 

.subscribe(value => console.log(value)); </pre>



<p><strong>Voilà! RxJS naprawdę ułatwia życie!</strong></p>



<h2 class="wp-block-heading" id="Subskrybcje">Subskrybcje</h2>



<p>Powyżej wspomniałem o możliwości subskrypcji do strumienia. Kolejny termin, który brzmi skomplikowanie (ale wcale taki skomplikowany nie jest!). Subskrybcja to po prostu podłączenie się do strumienia. Każdy observable posiada metodę <strong>subscribe(),</strong> do której możemy przekazać parametry na dwa sposoby: jako obiekt z metodami lub jako zestaw callbacków. Obiekt przekazany do metody subscribe nazywamy <strong>observerem</strong>.</p>



<h2 class="wp-block-heading" id="Observer">Observer</h2>



<p>Observer posiada trzy składowe:</p>



<ul class="wp-block-list">
<li>pierwsza metoda (<strong>next</strong>) jest wykonana, jeśli uda nam się odebrać wartość ze strumienia. Każda nowa wartość powoduje wywołanie tej metody,</li>



<li>druga metoda (<strong>error</strong>) jest wykonana, jeśli w strumieniu wystąpi błąd, na przykład w zapytaniu HTTP dostaniemy status 500. W przypadku wystąpienia błędu nasz observer nie przejdzie dalej i nie wykona metody complete, a tym samym zostanie zaznaczony jako closed i przestanie emitować wartości,</li>



<li>trzecia metoda (<strong>complete</strong>) jest wykonana w momencie, gdy strumień wyemituje ostatnią wartość.</li>
</ul>



<h2 class="wp-block-heading" id="RxJS-–-zalety">RxJS – zalety</h2>



<p>Biblioteka RxJS niewątpliwie ułatwia rozwój aplikacji. Możemy ją zintegrować właściwie z dowolnym <a href="https://nearshore-it.eu/pl/artykuly/najlepsze-frameworki-frontendowe" data-type="jpro" data-id="58320">frontendowym frameworkiem</a> (<strong>Angular</strong>, <strong>React</strong>). Również użycie z czystym JavaScriptem nie stanowi problemu. Do dyspozycji mamy ogromną liczbę operatorów, które pozwalają nam na dowolną modyfikację naszych strumieni. Stale pojawiające się aktualizacje sprawiają, że kolejne wydania biblioteki są coraz prostsze w użyciu. Dzięki RxJS zdecydowanie możemy przyspieszyć naszą pracę, jak również poprawić jakość wytwarzanego oprogramowania.</p>



<h2 class="wp-block-heading" id="RxJS-–-wady">RxJS – wady</h2>



<p>Tutaj zdecydowanie trudniej jest mi coś napisać niż w przypadku zalet. Pracując na co dzień z Angularem, nie wyobrażam sobie napisania choćby jednego komponentu bez użycia biblioteki RxJS. Na pewno rzeczą, która sprawia trudność – zwłaszcza początkującym programistom – jest<strong> testowanie kodu wykorzystującego RxJS</strong>. Testowanie takiego kodu wymaga znajomości wielu dodatkowych technik oraz narzędzi. Na szczęście RxJS ma na to swoje rozwiązanie i tu z pomocą przychodzi nam <strong>RxJS Marbles </strong>(umożliwia testowanie asynchronicznego kodu RxJS synchronicznie i krok po kroku za pomocą narzędzia testowego <strong>RxJS TestScheduler</strong> oraz przy użyciu wirtualnych kroków czasowych), jednak jest to dość obszerny temat, któremu można by poświęcić nowy wpis.</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image is-style-default">
<figure class="aligncenter size-full"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_2022.10.26_graphic_2.png" alt="RXJS - programowanie reaktywne" class="wp-image-68372" title="Wprowadzenie do funkcjonalnego programowania reaktywnego w JavaScript z RxJS 10"></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading" id="Podsumowanie">Podsumowanie</h2>



<p>Powyższe informacje stanowią bardzo ogólny opis programowania reaktywnego oraz biblioteki RxJS. O każdym z powyższych tematów śmiało mógłby powstać oddzielny artykuł, a mój to zaledwie kropla w morzu – wiele aspektów zostało pominiętych.</p>



<p>Jednak bez dwóch zdań używanie RxJS stało się standardem w tworzeniu nowoczesnych i wydajnych aplikacji. Ciągły rozwój i wsparcie dla najpopularniejszych frameworków sprawia, że RxJS jest zdecydowanie najczęściej używaną biblioteką ułatwiającą zapanowanie nad asynchronicznością.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/programowanie-reaktywne-w-js-z-rxjs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mikroserwisy – czy to jeszcze rewolucja i nowa jakość czy już standard w projektach?</title>
		<link>https://nearshore-it.eu/pl/artykuly/mikroserwisy-nowa-jakosc-w-miedzynarodowych-projektach-it/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/mikroserwisy-nowa-jakosc-w-miedzynarodowych-projektach-it/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Wieczorek]]></dc:creator>
		<pubDate>Wed, 10 Nov 2021 07:11:19 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Application development]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Trendy]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/mikroserwisy-nowa-jakosc-w-miedzynarodowych-projektach-it/</guid>

					<description><![CDATA[Mikroserwisy są odpowiedzią na problemy związane z tworzeniem i utrzymaniem monolitycznych systemów. W czasie, gdy aplikacje muszą być stale rozwijane, a jednocześnie dostępne dla użytkowników, mikrousługi stają się state-of-the-art w rozwoju oprogramowania. W jakich projektach się sprawdzą, a w których rozsądniej jest pozostać przy konstrukcji monolitu?]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">Idź do:</p>
    <ol>
                    <li><a href="#Mikroserwisy-ich-popularnosc-rosnie">1.  Mikroserwisy – ich popularność rośnie</a></li>
                    <li><a href="#Jak-architektura-mikroserwisow-odpowiada-dzis-na-potrzeby-rozwoju-systemow">2.  Jak architektura mikroserwisów odpowiada dziś na potrzeby rozwoju systemów?</a></li>
                    <li><a href="#Bolaczki-monolitycznej-aplikacji">3.  Bolączki monolitycznej aplikacji</a></li>
                    <li><a href="#Zalety-wykorzystania-architektury-mikroserwisow">4.  Zalety wykorzystania architektury mikroserwisów</a></li>
                    <li><a href="#Wady-mikroserwisow">5.  Wady mikroserwisów</a></li>
                    <li><a href="#Mikrouslugi-a-podejscie-DDD">6.  Mikrousługi a podejście DDD</a></li>
                    <li><a href="#Mikroserwisy-w-praktyce-case-study">7.  Mikroserwisy w praktyce – case study</a></li>
                    <li><a href="#Podsumowujac-czy-architektura-mikroserwisowa-sprawdzi-sie-w-moim-projekcie">8.  Podsumowując: czy architektura mikroserwisowa sprawdzi się w moim projekcie?</a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="Mikroserwisy-ich-popularnosc-rosnie">Mikroserwisy – ich popularność rośnie</h2>



<p>Pojęcie architektury mikroserwisowej pojawiło się po raz pierwszy na scenie IT w okolicach roku 2013. Od tego czasu jej popularność wydaje się poruszać tylko w jednym kierunku – w górę! Potwierdzenie takiej hipotezy możemy znaleźć na przykład w raporcie <a href="https://www.oreilly.com/radar/microservices-adoption-in-2020" target="_blank" rel="noopener">„Microservices adoption”</a> przygotowanym przez firmę O’Reilly w roku 2020, z którego wynika, że 77% firm, w których pracują respondenci, stosują taką architekturę. Jednocześnie aż <strong>92% pytanych określiło zastosowanie mikroserwisów jako sukces</strong>&nbsp; z perspektywy oczekiwanych zysków, które przynosi takie podejście.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.11.10_graphic_1.png" alt="architektura mikroserwisów" class="wp-image-36081" title="Mikroserwisy – czy to jeszcze rewolucja i nowa jakość czy już standard w projektach? 11"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>W innej ankiecie przeprowadzonej przez<a href="https://www.ibm.com/account/reg/us-en/signup?formid=urx-49970" target="_blank" rel="noopener"> IBM Market Development &amp; Insights</a> o opinię zapytanych zostało ponad 1200 osób z branży IT, w tym dyrektorzy techniczni, menedżerowie i programiści pracujący w firmach, które stosują lub planują zastosować architekturę mikroserwisową.</p>



<p>Wyniki są jednoznaczne:</p>



<ul class="wp-block-list">
<li><strong>87%</strong> użytkowników zgadza się, że wysiłek oraz koszty poniesione na wdrożenie architektury mikroserwisowej opłacały się.</li>



<li><strong>84%</strong> użytkowników zgadza się, że stosowanie mikroserwisów ułatwia pracę obecnym pracownikom oraz pozwala na przyciągnięcie nowych.</li>



<li><strong>77%</strong> użytkowników zgadza się, że mikroserwisy są sprawdzonym i niezawodnym modelem tworzenia aplikacji.</li>
</ul>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.11.10_graphic_2.png" alt="architektura mikroserwisów" class="wp-image-36082" title="Mikroserwisy – czy to jeszcze rewolucja i nowa jakość czy już standard w projektach? 12"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Chociaż jest to oczywiście bardzo wątpliwa miara, z własnej perspektywy programisty – sądząc po opisach projektów w ofertach pracy – mógłbym stwierdzić, że praktycznie większość projektów jest aktualnie tworzona w architekturze mikroserwisowej. Pomimo że na takie opisy musimy spojrzeć z przymrużeniem oka, widać, że <strong>mikroserwisy szybko stają się standardem w świecie IT.</strong></p>



<h2 class="wp-block-heading" id="Jak-architektura-mikroserwisow-odpowiada-dzis-na-potrzeby-rozwoju-systemow">Jak architektura mikroserwisów odpowiada dziś na potrzeby rozwoju systemów?</h2>



<p>Jednym z największych wyzwań architektury mikroserwisowej jest silna zależność od infrastruktury (serwerowej, sieciowej itp.), a co za tym idzie – zwiększona potrzeba inwestycji w jej tworzenie. Jeszcze kilka lat temu było to jednak dużo większym wyzwaniem niż dzisiaj. W odpowiedzi na potrzeby nowego modelu powstał szeroki wachlarz narzędzi, które usprawniają pracę w rozproszonym środowisku.</p>



<ul class="wp-block-list">
<li><strong>Kontenery</strong> – na potrzeby <a href="https://nearshore-it.eu/pl/artykuly/azure-serverless-workflow-orchestration">orkiestracji</a> serwisami powstały rozwiązania do zarządzania, automatyzacji i skalowania aplikacji kontenerowych. Dzisiaj możemy wybierać spośród wielu narzędzi, od prostych i niewymagających, jak <strong>Docker Swarm,</strong> po zakrojone na największą skalę rozwiązania enterprise, jak chyba najpopularniejszy <strong>Kubernetes</strong> lub <strong>Openshift. </strong>Dodatkowo dostępne są rozwiązania chmurowe, jak <strong>AWS Fargate</strong> czy <strong>Google Cloud Run</strong>. Każda z platform chmurowych oferuje również zarządzane przez siebie serwisy Kubernetes, jak <strong>AWS EKS</strong> lub <strong>Google GKE.</strong> Wszystkie wymienione narzędzia w znacznym stopniu zmniejszają dzisiaj próg wejścia do projektów opartych na mikroserwisach pod względem infrastruktury serwerowej. Należy jednak liczyć się z kosztami ich utrzymywania.</li>



<li><strong>Service Mesh</strong> – w odpowiedzi na wyzwania związane z silną zależnością od infrastruktury sieciowej powstało wiele rozwiązań, z których najpopularniejszy jest obecnie <a href="https://nearshore-it.eu/pl/artykuly/service-mesh-ale-komu-to-potrzebne">model Service Mesh.</a> Tutaj znowu mamy wybór pomiędzy lekkimi rozwiązaniami jak <strong>Linkerd, Kuma czy Maesh</strong> a bardziej wymagającymi, jak <a href="https://nearshore-it.eu/pl/artykuly/mikroserwisy-service-mesh-z-istio"><strong>Istio</strong></a><strong>,</strong> oraz rozwiązaniami chmurowymi, jak <strong>AWS App Mesh.</strong> Jak widać, stworzenie infrastruktury sieciowej dla swojej aplikacji mikroserwisowej nie stanowi dzisiaj tak dużego wyzwania jak kiedyś, chociaż sama zależność od sieci jest i zawsze pozostanie wyzwaniem.</li>



<li><strong>Narzędzia do monitorowania</strong> – cytując głównego inżyniera firmy Lyft, Matta Kleina, który brał udział w przejściu firmy z monolitu na mikroserwisy:</li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>Inną istotną zmianą, która pojawia się wraz z rozwojem mikroserwisów, jest obecność sieci jako niestabilnego elementu, którego nie da się uniknąć. Każdy programista musi w końcu poradzić sobie z problemami sieciowymi, zarówno jeśli chodzi o transport, jak i o znacznie bardziej złożone narzędzia wymagane do debugowania.</em></p>
</blockquote>



<p>Wspomniane wyżej narzędzia wspierające pracę i debugowanie aplikacji kontenerowej również przeżyły rozkwit i dzisiaj możemy wspierać się narzędziami do monitorowania, logowania i tracingu. Rozwiązania takie jak <strong>Prometheus, ELK</strong> czy <strong>AWS CloudWatch</strong> pozwalają sprostać wyzwaniom utrzymywania lub debugowania aplikacji w rozproszonym środowisku.</p>



<h2 class="wp-block-heading" id="Bolaczki-monolitycznej-aplikacji">Bolączki monolitycznej aplikacji</h2>



<p>Powstanie i ostateczny sukces mikroserwisów nie wziął się oczywiście z niczego. Jest to raczej odpowiedź na trudności związane z klasycznym podejściem, które w wielu przypadkach przeważają nad plusami podejścia monolitycznego.</p>



<h3 class="wp-block-heading">Z perspektywy biznesu i użytkowników</h3>



<p>Z perspektywy biznesowej możemy wymienić wiele wad, które mogą wpłynąć na doświadczenia użytkowników i tym samym – na ostateczny sukces aplikacji:</p>



<ul class="wp-block-list">
<li>Wprowadzanie nawet najmniejszej zmiany wymaga reinstalacji całej aplikacji, co prowadzi do tymczasowej niedostępności aplikacji, która w nowoczesnym świecie jest praktycznie niedopuszczalna dla komercyjnych rozwiązań.</li>



<li>Poszczególne komponenty systemu są ze sobą ściśle powiązane, co oznacza, że nawet mała zmiana w kodzie może negatywnie wpłynąć na całą aplikację, a tym samym być odczuwalna dla 100% jej użytkowników.</li>



<li>Trudności nastręcza skalowanie aplikacji w odpowiedzi na zmienny ruch. Niemożliwe jest też oczywiście skalowanie poszczególnych komponentów systemu, a tylko całej aplikacji. W momencie przeciążenia aplikacja może stać się niedostępna dla części użytkowników.</li>



<li>Brak skalowalności może się przekładać na wyższe koszty utrzymania aplikacji.</li>



<li>Spowolnienie prędkości rozwoju i udostępniania nowej funkcjonalności.</li>



<li>Zdecydowanie zmniejszona możliwość zastosowania nowych technologii, których wprowadzenie byłoby zbyt kosztowne i wymagałoby poświęcenia więcej czasu przez programistów (czy nawet zatrudnienia nowych).</li>
</ul>



<h3 class="wp-block-heading">Z perspektywy developera</h3>



<p>Patrząc z perspektywy developera pracującego nad monolitem, możemy dodatkowo wymienić jeszcze kilka wad:</p>



<ul class="wp-block-list">
<li>Spora baza kodu jest trudna w zrozumieniu, co od nowego programisty wymaga dużo czasu na poznanie i wdrożenie. Spowalnia ona również codzienny cykl wprowadzania zmian i ich testowania (pamiętajmy, że każda, nawet drobna zmiana, może mieć wpływ na całą aplikację).</li>



<li>Rozmyta odpowiedzialność oraz brak poczucia własności kodu może wpływać demotywująco na programistę. W przeciwieństwie do całkowitej własności części systemu, którego czujemy się autorem w przypadku tworzenia i utrzymywania konkretnych mikrousług.</li>



<li>Trudność we wdrożeniu nowych, interesujących technologii, ponieważ każda taka inicjatywa oznacza wprowadzenie zmian w całej bazie kodu aplikacji.</li>



<li>Mniejsze możliwości rozwoju osobistego – w dynamicznie zmieniającym się świecie IT rozważne jest, aby developer ciągle się rozwijał i zawsze dysponował aktualną wiedzą. Praca nad aplikacją monolityczną może nie być najlepszym krokiem, gdyż nie ma się styczności z szeroką wiedzą wymaganą w świecie mikroserwisów.</li>
</ul>



<h2 class="wp-block-heading" id="Zalety-wykorzystania-architektury-mikroserwisow">Zalety wykorzystania architektury mikroserwisów</h2>



<p>Przejdźmy teraz do możliwości i udogodnień dostępnych przy wykorzystaniu mikroserwisów.</p>



<h3 class="wp-block-heading">Z perspektywy biznesu i użytkowników</h3>



<ul class="wp-block-list">
<li>Łatwa redundancja elementów (czyli duplikowanie poszczególnych komponentów celem zapewnienia ciągłości pracy w razie awarii) i ich skalowanie, zgodnie z aktualnym zapotrzebowaniem, a tym samym większa dostępność systemu. Maleje tym samym ryzyko, że użytkownik nie będzie mógł skorzystać z naszej aplikacji.</li>



<li>Luźne powiązanie poszczególnych serwisów pozwala na niezależny rozwój funkcjonalności i szybsze ich wdrożenie.</li>



<li>Wdrożenia mogą następować niezależnie od siebie i praktycznie nie wpływają na dostępność całości systemu dla użytkowników.</li>



<li>Mikroserwisy są idealnie dostosowane do wykorzystania <a href="https://bulldogjob.pl/articles/1047-serverless-czym-jest-i-jak-dziala" target="_blank" rel="noopener">architektury typu serverless</a>, która w odpowiednich zastosowaniach pozwoli zaoszczędzić na kosztach infrastruktury.</li>



<li>Łatwiejsze testowanie małych komponentów pozwala na uniknięcie wystąpienia uciążliwych dla użytkowników bugów.</li>



<li>Wdrożenie nowych technologii, z korzyścią dla użytkownika, jest zdecydowanie łatwiejsze i może odbywać się na poziomie poszczególnych serwisów.</li>
</ul>



<h3 class="wp-block-heading">Z perspektywy developerów</h3>



<p>Z zastosowaniem mikroserwisów łączy się też kilka pozytywów dla pracujących z nimi developerów:</p>



<ul class="wp-block-list">
<li>Pojedyncze usługi są łatwiejsze w zrozumieniu, ich baza kodu jest też odpowiednio mniejsza. Ułatwia to pracę nad nowymi funkcjonalnościami i ich <a href="https://nearshore-it.eu/pl/artykuly/quality-assurance-czyli-jak-zagwarantowac-jakosc-i-bezpieczenstwo-w-projektach-it">testowaniem</a>, ale również usprawnia wdrożenie nowej osoby w projekt.</li>



<li>Każdy z twórców danej usługi czuje się za nią odpowiedzialny i dobrze zna domenę biznesową powierzonej mu części.</li>



<li>Możliwość eksperymentowania i poszerzania wiedzy o nowych technologiach przy tworzeniu nowych funkcjonalności.</li>



<li>Mniejsza koncentracja wiedzy wśród programistów, co pozwala uniknąć sytuacji, w której brak kluczowej osoby może okazać się poważnym problemem.</li>



<li>Odpowiedzialność za poszczególne komponenty jest podzielona pomiędzy oddzielne zespoły, co pozwala na skuteczne dyżurowanie i szybką reakcję odpowiednich dla danego problemu osób. </li>
</ul>



<p><strong>Przeczytaj także:</strong> <a href="https://nearshore-it.eu/pl/artykuly/mikroserwisy-service-mesh-z-istio">Mikroserwisy – Service Mesh z Istio. Poznaj Istio i możliwości jakie daje.</a></p>



<h2 class="wp-block-heading" id="Wady-mikroserwisow">Wady mikroserwisów</h2>



<h3 class="wp-block-heading">Z perspektywy biznesu</h3>



<ul class="wp-block-list">
<li>Początkowy koszt wykonania aplikacji w architekturze rozproszonej może być wyższy niż w przypadku monolitu. Podwyższony koszt to przede wszystkim wydatek na infrastrukturę oraz zaangażowanie odpowiednich specjalistów DevOps, odpowiedzialnych za jej utrzymanie.</li>



<li>Ryzyko, że realizacja aplikacji będzie utrudniona lub nawet się nie powiedzie, jest większe z powodu nieodłącznej złożoności takiej architektury.</li>



<li>Wdrożenie takiej architektury wymaga zmiany podejścia całego zespołu pracującego nad aplikacją. Decyzyjność przesuwa się od menedżerów i architektów w stronę poszczególnych zespołów. Z taką autonomią przychodzi większa potrzeba skutecznej komunikacji i współpracy pomiędzy zespołami.</li>
</ul>



<h3 class="wp-block-heading">Z perspektywy developera</h3>



<ul class="wp-block-list">
<li>Funkcjonalność wymagająca bezwzględnej spójności danych (transakcje bankowe itp.) jest trudniejsza do implementacji, ponieważ wymaga dodatkowej koordynacji całego procesu, który może być realizowany w kliku usługach. W aplikacji monolitycznej taki problem byłby rozwiązany za pomocą transakcji na poziomie bazy danych.</li>



<li>Debugowanie może być utrudnione z powodu rozproszenia logiki w wielu usługach, których logi mogą zawierać wskazówki o błędzie. Dodatkowymi źródłami błędów mogą okazać się punkty komunikacji pomiędzy poszczególnymi usługami.</li>



<li>Testowanie integracyjne nowych funkcjonalności staje się bardziej skomplikowane, ponieważ nie ma możliwości przetestowania całego systemu rozproszonego.</li>
</ul>



<h2 class="wp-block-heading" id="Mikrouslugi-a-podejscie-DDD"><strong>Mikrousługi a podejście DDD</strong></h2>



<p>Większość korzyści płynących z zastosowania architektury rozproszonej jest efektem stworzenia prawidłowego podziału odpowiedzialności poszczególnych usług i wyznaczenia sposobu komunikacji między nimi. Celem jest stworzenie silnej spójności serwisów i jednocześnie luźnego powiązania pomiędzy nimi. Innymi słowy, rzeczy, które zwykle wymagają wspólnej zmiany, powinny należeć do jednego serwisu. Bez odpowiedniego podziału zamiast korzyści, jak niezależna implementacja czy skalowalność usług, możemy skończyć z niewydajnym lub trudnym w utrzymaniu projektem. W praktyce jest to oczywiście trudniejsze do zrealizowania niż w teorii – wstępne założenia lub późniejsze wymagania ulegają zmianie. Z tego powodu możliwość łatwego wprowadzania zmian jest kolejnym krytycznym aspektem podczas projektowania każdej aplikacji.</p>



<p>Podejście <strong>Domain-driven design (DDD)</strong> jest kluczowym narzędziem podczas projektowania architektury mikroserwisowej, tak przy rozbijaniu aplikacji monolitycznej, jak i tworzeniu aplikacji od zera.</p>



<h3 class="wp-block-heading">Czym jest DDD? Czyli jak okiełznać system podczas tworzenia oprogramowania</h3>



<p>DDD zapoczątkowane w książce Erica Evansa to zestaw zasad i wzorców, których celem jest wsparcie tworzenia aplikacji rozproszonych w oparciu o model domeny biznesowej będącej tematem tworzonego oprogramowania. Zespół programistów wraz z ekspertami domeny biznesowej tworzą model biznesowy w wypracowanym wspólnym języku, tzw. <em>ubiquitous language</em><em>. </em>Następnie stworzony model jest tłumaczony na poszczególne usługi, ustalane są protokoły komunikacji między nimi oraz tworzone są zespoły odpowiedzialne za poszczególne serwisy. W całym procesie&nbsp; pomocny może być dodatkowo <a href="https://en.wikipedia.org/wiki/Event_storming" target="_blank" rel="noopener">event storming</a>. Wzorce DDD mają na celu ułatwienie zrozumienia domeny i zależności w niej zachodzących. Od tego już niedaleko do wyznaczenia granic w domenie, a tym samym wypracowania podziału na usługi zmapowane na domenę biznesową.</p>



<h2 class="wp-block-heading" id="Mikroserwisy-w-praktyce-case-study">Mikroserwisy w praktyce – case study</h2>



<p>W istniejącej od wielu lat<a href="http://jcommerce.local/klienci/pionierskie-rozwiazanie-developerow-java-dla-e-commerce" target="_blank" rel="noopener"> </a>platformie e-commerce pojawiło się nowe wymaganie biznesowe, polegające na masowym tworzeniu nowych ofert na bazie plików. Narzędzie miało być głównie stosowane przez sprzedawców oferujących szeroki asortyment, którzy w ten sposób mogliby usprawnić i zautomatyzować interakcję z platformą w kwestii tworzenia i edycji swoich ofert.</p>



<p>Wspomniana platforma, chociaż została stworzona jako monolit, od dawna jest już rozbita i rozwijana w architekturze mikroserwisowej. Zadanie zlecone jednemu z zespołów Inetum polegało więc na stworzeniu nowej mikrousługi (ostatecznie powstało ich kilka) odpowiedzialnej za realizację tej funkcjonalności. Prace nad rozwiązaniem postępowały bez ingerencji w resztę usług aplikacji, której rozwój mógł postępować niezależnie. Jedynym punktem styku z resztą platformy stała się inna mikrousługa, a szczegóły komunikacji i implementacji zostały ustalone pomiędzy zespołami odpowiedzialnymi za obie usługi. Również decyzje o wyborze technologii (jak baza danych czy nawet język programowania) pozostawały w dużej mierze w gestii zespołu. Po wdrożeniu na produkcję zespół Inetum jest w stanie dynamicznie skalować ilość instancji usługi adekwatnie do liczby zapytań od użytkowników.</p>



<p>Taka autonomia jest kluczowa przy rozwoju aplikacji, nad którą kolektywnie pracują nawet setki zespołów. Trudno sobie wręcz wyobrazić skuteczne wdrożenie takiej funkcjonalności, gdyby cala platforma była nadal monolitem.</p>



<h2 class="wp-block-heading" id="Podsumowujac-czy-architektura-mikroserwisowa-sprawdzi-sie-w-moim-projekcie">Podsumowując: czy architektura mikroserwisowa sprawdzi się w moim projekcie?</h2>



<p>Odpowiedź na to pytanie musi być niestety wymijająca – <strong>to zależy. </strong>Decydując się na dany model, akceptujemy kompromis, czyli przyjmujemy go razem z jego mocnymi i słabymi stronami.</p>



<h3 class="wp-block-heading">Gdy chcemy rozbić monolit</h3>



<p>Jeżeli rozważamy rozbicie istniejącej aplikacji monolitycznej, decyzja jest może prostsza, zmotywowana wszystkimi bolączkami, które nastręcza monolit. <strong>W tym przypadku jednym ze sprawdzonych podejść jest odcinanie mniejszych serwisów z głównego bloku,</strong> aż w końcu nowe funkcjonalności będą mogły być tworzone w całkowitej izolacji, a mniejszy centralny monolit będzie stopniowo wygaszany.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.11.10_graphic_3.png" alt="architektura mikroserwisowa całej aplikacji" class="wp-image-36083" title="Mikroserwisy – czy to jeszcze rewolucja i nowa jakość czy już standard w projektach? 13"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">Gdy tworzymy aplikację od podstaw</h3>



<p>Jeżeli jednak rozpoczynamy tworzenie aplikacji od zera, jednym z kluczowych względów, na którym możemy oprzeć decyzję, jest rozmiar docelowej aplikacji. W przypadku tworzenia MVP aplikacji, najważniejsza jest szybkość dostarczenia funkcjonalności kosztem innych priorytetów. Zgodnie z zasadą <a href="https://martinfowler.com/bliki/Yagni.html" target="_blank" rel="noopener">YAGNI</a> (<em>You Ain’t Gonna Need It</em>) nie ma sensu inwestować w zastosowanie zbyt wyszukanych narzędzi, jeśli nie mamy pewności, że aplikacja będzie się cieszyć odpowiednim poziomem zainteresowania.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.11.10_graphic_4.png" alt="architektura mikroserwisów" class="wp-image-36084" title="Mikroserwisy – czy to jeszcze rewolucja i nowa jakość czy już standard w projektach? 14"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>Taka sytuacja przemawia więc za zastosowaniem monolitu, który dopiero w dalszej fazie zostanie podzielony – ciekawym rozwiązaniem może być zastosowanie architektury tzw. modularnego monolitu, w której funkcjonalności rozbite są na poszczególne moduły tworzone w ramach jednej aplikacji.</strong></p>



<p>Jeśli jednak wiemy, że rozmiary docelowej aplikacji uzasadniają wstępną inwestycję, wtedy architektura mikroserwisowa jest jak najbardziej rozsądnym wyborem.</p>



<p><strong>Przeczytaj także: </strong><a href="https://nearshore-it.eu/pl/artykuly/kim-jest-devops-i-jak-wspiera-projekty-it/" target="_blank" data-type="URL" data-id="https://nearshore-it.eu/pl/artykuly/kim-jest-devops-i-jak-wspiera-projekty-it" rel="noreferrer noopener"> Kim jest DevOps i jak wspiera projekty IT? </a></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/mikroserwisy-nowa-jakosc-w-miedzynarodowych-projektach-it/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mikroserwisy – Service Mesh z Istio</title>
		<link>https://nearshore-it.eu/pl/artykuly/mikroserwisy-service-mesh-z-istio/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/mikroserwisy-service-mesh-z-istio/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Wieczorek]]></dc:creator>
		<pubDate>Wed, 22 Sep 2021 07:22:16 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[Application development]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/mikroserwisy-service-mesh-z-istio/</guid>

					<description><![CDATA[Jednym z wyzwań dynamicznej architektury mikroserwisowej jest tworzenie i utrzymywanie połączeń pomiędzy jej elementami. Poszczególne serwisy mogą być dynamicznie dodawane, aktualizowane i usuwane, dodatkowo każdy z nich może być zeskalowany do wielu instancji, niekoniecznie w tej samej wersji aplikacji. Niewątpliwie poziom skomplikowania wymusza potrzebę posiadania mechanizmu, który pozwoli uprościć warstwę komunikacji i zdejmie z developerów większość ciężaru wiążącego się z pracą w tym środowisku. Jednym z takich mechanizmów jest Service Mesh, w którym wykorzystany jest tzw. wzorzec sidecar, czyli element proxy przypięty do każdego kontenera aplikacji. Razem proxy obsługują komunikację w klastrze Kubernetesa, tworząc siatkę. Mechanizm siatki pozwala na optymalizację wydajności sieci, ułatwia jej zabezpieczenie oraz umożliwia monitorowanie ruchu. W poprzednim artykule znajdziecie więcej szczegółów na temat <a href="https://nearshore-it.eu/pl/artykuly/service-mesh-ale-komu-to-potrzebne">Service Mesh</a>, a w tym artykule bliżej przyjrzyjmy się Istio i możliwościom, jakie daje.]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">Przejdź do:</p>
    <ol>
                    <li><a href="#czym-jest-istio">1.  Czym jest Istio</a></li>
                    <li><a href="#co-dostajemy-prosto-z-pudelka">2.  Co dostajemy prosto z pudełka</a></li>
                    <li><a href="#przyklad-uzycia-istio-zarzadzanie-ruchem-sieciowym">3.  Przykład użycia Istio – zarządzanie ruchem sieciowym</a></li>
                    <li><a href="#podsumowanie">4.  Podsumowanie</a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="czym-jest-istio">Czym jest Istio</h2>



<p>Istio jest implementacją koncepcji Service Mesh, projektem open-source, stworzonym przez zespół Google i IBM we współpracy z zespołem Envoy z firmy Lyft. Istio wykorzystuje sprawdzone proxy Envoya, aby zapewnić korzyści oferowane przez takie podejście do warstwy sieci w klastrze. Główne zalety to: dodanie podstawowej konfiguracji, która dostarcza połączenie sieciowe, oraz zabezpieczenie i monitorowanie istniejących serwisów bez zmian w kodzie istniejących aplikacji.</p>



<h3 class="wp-block-heading" id="kubernetes-istio-jak-to-dziala-razem">Kubernetes – Istio: jak to działa razem?</h3>



<p>Istio w ekosystemie Kubernetesa dzieli się na dwa komponenty: <strong>data plane i control plane.</strong></p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.09.22_obraz1_b.png" alt="Istio Service Mesh" class="wp-image-35798" title="Mikroserwisy – Service Mesh z Istio 15"></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>Data plane</strong> to kolektywna nazwa dla wszystkich proxy Envoy, przez które przechodzi komunikacja w klastrze. Proxy przechwytują cały ruch sieciowy i nakładają na niego reguły dostarczone przez nas w konfiguracji. Niektóre z możliwości, jakie daje nam Istio z wykorzystaniem Envoya:</p>



<ul class="wp-block-list">
<li>Szczegółowa kontrola ruchu sieciowego za pomocą zasad routingu dla HTTP, gRCP, WebSocket oraz pakietów TCP.</li>



<li>Odporność na problemy w funkcjonowaniu sieci, takie jak retry, failovers i circut breakery.</li>



<li>Zabezpieczenie sieci za pomocą polityk bezpieczeństwa oraz limitowanie obciążenia kontrolowane konfiguracyjnie.</li>
</ul>



<p><strong>Control plane (Istiod)</strong> to zestaw komponentów, które dynamicznie zarządzają działaniem naszego Service Mesh. Poszczególne komponenty są odpowiedzialne za:</p>



<ul class="wp-block-list">
<li>Service discovery i load balancing (Istio utrzymuje tzw. service registry, dzięki któremu proxy Envoya mogą kierować ruchem i rozkładać obciążenie sieciowe na wiele instancji serwisów).</li>



<li>Konfigurację routingu z poziomu plików konfiguracyjnych, które są tłumaczone i następnie propagowane do niskopoziomowego API Envoya.</li>



<li>Obsługę bezpieczeństwa komunikacji wewnątrz klastra za pomocą mTSL oraz zarządzanie certyfikatami dla tejże komunikacji.</li>
</ul>



<h2 class="wp-block-heading" id="co-dostajemy-prosto-z-pudelka"><strong>Co dostajemy prosto z pudełka</strong></h2>



<p>Instalację Istio możemy rozpocząć od wykorzystania jednego z przygotowanych profili konfiguracji, a następnie wprowadzać dodatkowe zmiany adekwatnie do naszych potrzeb.</p>



<p>Na początek najlepiej jest skorzystać z <span class="NormalTextRun CommentStart BCX0 SCXW149707252">profilu domyślnego</span><span class="NormalTextRun BCX0 SCXW149707252">,</span>&nbsp;który poza bazową konfiguracją <em>control plane</em> i <em>proxy</em> dostarcza dodatkowo komponent <em>istio-ingressgateway. </em>Pozwala nam on na monitorowanie i kontrolę ruchu sieciowego wchodzącego do wewnątrz klastra Kubernetesa.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.09.22_tabela.png" alt="Istio" class="wp-image-35779" title="Mikroserwisy – Service Mesh z Istio 16"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>W bazowej instalacji, bez jakichkolwiek dodatkowych zmian, otrzymujemy w pakiecie możliwości monitorowania ruchu w klastrze, automatycznie zbierane są również <a href="https://istio.io/latest/docs/reference/config/metrics/" target="_blank" rel="noopener">metryki</a> (takie jak liczba oraz czas zapytań i odpowiedzi). Jednocześnie możemy też śledzić każde zapytanie skierowane do klastra, jak również wykrywać problemy w komunikacji, takie jak wąskie gardła lub zwiększenie błędnych odpowiedzi z jednego z mikroserwisów.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.09.22_obraz2.png" alt="Istio Service Mesh zarządzanie ruchem sieciowym" class="wp-image-35782" title="Mikroserwisy – Service Mesh z Istio 17"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Dodatkowo cały ruch sieciowy wewnątrz klastra jest automatycznie szyfrowany z użyciem mechanizmu mTLS, czyli wzajemnego uwierzytelniania mikroserwisów za pomocą certyfikatów X.509, których zarządzaniem również zajmuje się Istio.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.09.22_obraz3_b.png" alt="Istio Service Mesh" class="wp-image-35799" title="Mikroserwisy – Service Mesh z Istio 18"></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Jak widać, sporo zyskujemy już przez samo użycie Istio, bez jakichkolwiek dodatkowych konfiguracji z naszej strony. Jednak przy niewielkim wysiłku wykorzystanie Istio otwiera przed nami bardzo dużo dodatkowych możliwości. Poniżej opiszę jedną z nich.</p>



<h2 class="wp-block-heading" id="przyklad-uzycia-istio-zarzadzanie-ruchem-sieciowym">Przykład użycia Istio – zarządzanie ruchem sieciowym</h2>



<p>Załóżmy, że pracujemy nad aplikacją złożoną z kilku aplikacji, której architekturę przedstawiono na poniższym schemacie.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.09.22_obraz4.png" alt="Istio Mesh" class="wp-image-35784" title="Mikroserwisy – Service Mesh z Istio 19"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>W szczególności zwróćmy uwagę, że zainstalowano trzy wersje serwisu ‘review’, chociaż na ten moment wydaje się, że ruch sieciowy trafia tylko do wersji v1.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.09.22_obraz5.png" alt=" class=" class="wp-image-35785" title="Mikroserwisy – Service Mesh z Istio 20"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Konfiguracja Istio potwierdza, że tylko wersja v1 może przyjmować zapytania z serwisu <em>productpage</em>. Załóżmy dodatkowo, że nieużywany na ten moment moduł <em>ratings</em> służy do &nbsp;nowej funkcjonalności, dostępnej dopiero od v2 usługi <em>reviews</em>. Jeśli w ten sytuacji chcielibyśmy skierować część zapytań (w naszej konfiguracji 10%) do nowej wersji usługi (tzw. canary deployment), możemy to zrobić za pomocą niewielkiej modyfikacji istniejącej konfiguracji.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.09.22_obraz6.png" alt="Istio Mesh" class="wp-image-35786" title="Mikroserwisy – Service Mesh z Istio 21"></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Efekt takiej zmiany na ruch sieciowy w naszej aplikacji wygląda następująco:</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.09.22_obraz7.png" alt=" class=" class="wp-image-35787" title="Mikroserwisy – Service Mesh z Istio 22"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Jak widać, około 10% ruchu do serwisu <em>reviews</em> trafia teraz do wersji v2, która prawidłowo komunikuje się z serwisem <em>ratings</em>. Kolejnymi krokami mogłyby być monitorowanie nowych usług i stopniowe manipulowanie wagami aż do ostatecznego całkowitego przejścia na nową wersję funkcjonalności.</p>



<p>Zwróćmy jednak uwagę, że ruch sieciowy w poprzednim przykładzie był kierowany do konkretnych wersji serwisu <em>reviews</em> losowo, tym samym nie mamy kontroli nad tym, pod jakim warunkiem lub dla jakiego użytkownika nowa funkcjonalność będzie dostępna.</p>



<p>W kolejnym przykładzie chcemy udostępnić dla użytkowników aplikacji możliwość wzięcia udziału w testowaniu nowej funkcjonalności. Wiąże się to z kierowaniem wybranej części ruchu sieciowego do nowej usługi na podstawie atrybutu zapytań HTTP. W realizacji tego zadania pomoże nam dodawanie niestandardowego headera do wszystkich zapytań (np. <em>x-beta</em>) i kierowanie ruchem na jego podstawie.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.09.22_obraz8.png" alt="Istio" class="wp-image-35788" title="Mikroserwisy – Service Mesh z Istio 23"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>Taka prosta zmiana w naszej początkowej konfiguracji pozwala na zrealizowanie opisanego wymagania.</strong></p>



<p>Alternatywnym podejściem do powyższej sytuacji, zmniejszającym ryzyko nieprawidłowego działania nowej funkcjonalności, jest wykorzystanie mechanizmu traffic mirroring. W tej konfiguracji decydujemy się kierować cały ruch sieciowy do stabilnej wersji v1, jednocześnie wysyłając kopię całego ruchu do wersji v2, która w tym momencie jest niedostępna dla użytkowników, ale możliwa jest analiza i testowanie niesprawdzonej wersji w środowisku produkcyjnym.</p>



<p>Poniższa konfiguracja umożliwia opisany wyżej <strong>traffic mirroring:</strong></p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.09.22_obraz9.png" alt=" class=" class="wp-image-35790" title="Mikroserwisy – Service Mesh z Istio 24"></figure></div>


<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>W tej konfiguracji 100% ruchu jest skierowane do wersji v1, jednocześnie 100% ruchu jest też kierowane do v2, z tym że użytkownik otrzyma odpowiedź zawsze ze stabilnej wersji serwisu. Możemy oczywiście kontrolować ilość ruchu odbijanego w stronę v2 za pomocą parametru konfiguracji <em>mirrorPercentage.</em></p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/JPro_2021.09.22_obraz7.png" alt="Istio Mesh" class="wp-image-35787" title="Mikroserwisy – Service Mesh z Istio 25"></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading" id="podsumowanie">Podsumowanie</h2>



<p>Istio to bardzo rozbudowane narzędzie, a opisane przykłady to tylko niewielka część jego dużo większych możliwości. I chociaż próg wejścia nie jest najmniejszy, to zdecydowanie jest warto ze względu na korzyści. Zdecydowanym ułatwieniem jest możliwość rozpoczęcia od domyślnej konfiguracji, która wymaga niewielu zmian w istniejącej aplikacji. Mam nadzieję, że ten artykuł zachęci was do wypróbowania Istio w waszych projektach.</p>



<p><strong>Przeczytaj także: </strong><a href="https://nearshore-it.eu/pl/artykuly/mikroserwisy-nowa-jakosc-w-miedzynarodowych-projektach-it"><strong>Mikroserwisy <em>–</em> nowa jakość w międzynarodowych projektach IT</strong></a></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/mikroserwisy-service-mesh-z-istio/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
