Mikroserwisy – o krok dalej

Poprzednio mówiłem dość powierzchownie o mikroserwisach w kontekście frontendu. Jednak jeśli go nie czytałeś to nic nie szkodzi - był to jedynie swojego rodzaju sneak peak.

Jest taki pomysł żeby zaszczepić ideę mikroserwisów również na warstwie frontendu. Myślę że można to teraz spotkać pod różnymi nazwami takimi jak np. CompositeUI, Microfrontends... Zastanówmy się nad tym jak obecnie podchodzimy do tematu.

Realizacja

Obecnie realizujemy warstwę widoku na kilka sposobów. Oczywiście będę tu generalizować, bo ile wdrożeń tyle pomysłów - aczkolwiek główny koncept pozostaje taki sam.

Monolit

W monolitycznych aplikacjach mamy monolityczny frontend. To chyba żadne odkrycie. Jednakże chcę zwrócić na to uwagę bo wrócimy do tego później. Otóż, tworząc aplikację typu monolit posiadamy w jednym repozytorium, jedną paczkę, jeden końcowy artefakt jako całość - backend & frontend. Zalety są niesamowite, pomijając tu absolutnie wielkość kodu, który mogą posiadać duuże monolity.

Przede wszystkim wdrażając aplikację wdrażamy ją wraz z UI - tworzącym jedną spójną całość. Nie paraliżują nas zmiany endpointów, nie musimy ich wersjonować. Po prostu deploy i działa. W podejściu mobile last, problem integracji to od dziś problem teamów mobilnych 🙂 Często jednak serwisy tego typu wykorzystują jeszcze server side rendering, a API jest oddzielną kwestią. Naturalną drogą ewolucji może być rozdzielenie frontendu od backendu.

just monolith

Monolit + REST ( or whatever )

Tworząc endpointy, dajmy na to restowe, wprowadza się interfejsy pomiędzy logiką a UI. Jest to podejście dobre o tyle, że pozwala w dużym stopniu zrównoleglić pracę. Frontendzi piszą swoje HTMLe, CSSy, JSy i inne cuda, a następnie się integrują gdy dana funkcjonalność zostanie zaimplementowana po stronie backendu.

monolith with rest communication

Moim skromnym zdaniem powstaje tu pewna próżnia. Separacja to jest coś co lubimy w programowaniu, oddzielamy, tworzymy warstwy, wiemy co gdzie i jak. Lecz jest pewne ALE - próżnia powstaje też pomiędzy zespołami, powstaje też przy integracji. Kto wie najlepiej jak wykorzystać udostępnione endpointy? Odpowiedź jest chyba oczywista - ich twórcy. Z tym że twórcy siedzą zapewne w innym pokoju, na innym piętrze, kraju, kontynencie, planecie.

Ok na tym etapie zapewne przesadzam, jednakże ten trend przekłada się na dalszą ewolucję.

Mikroserwisy + BFF

Oto mniej więcej rozłożenie wiedzy potrzebnej przy tym podejściu: Warstwa agregacyjna również musi być świadoma niemal wszystkiego: knowledge at microservices

BFF to taka warstwa agregacyjna dla mikroserwisów z którymi integruje się bezpośrednio frontend. Problem opisany wcześniej tutaj tylko się potęguje. Zespół od frontendu jest zapewne większy, ścieżki komunikacji się komplikują. Współdzielenie kodu frontendu przez wiele zespołów również nie jest dobrym pomysłem, każdy ciągnie w swoją stronę.
Wydanie wersji mikroserwisu udostępniającego publiczne API? Jest znacznie utrudnione w przypadku nawet drobnych zmian trzeba skonsultować to z innym zespołem, a z nim komunikują się wszystkie zespoły które tworzą jakieś publiczne API.

Oczywiście BFF może takie zmiany niwelować(kolejne miejsce pełne magii i wiedzy tajemnej), ale jednak co z dodawaniem funkcjonalności? Czy zespół frontendu nadąży? Ile wiedzy biznesowej musi posiadać ten zespół?

Wersjonowanie endpoinów, wieczne czekanie na poprawki i niepotrzebne nerwy. Sprawę nieco poprawia wykorzystanie GraphQL, ale czy aż tak bardzo?

Problem

Nie chcę tu powiedzieć że monolit jest najlepszym podejściem, jednak warto zwrócić uwagę na jego zalety. Moim zdaniem główną zaletą jest fakt że wdrażając aplikację, wdrażamy ją razem z pasującym i przetestowanym UI. Wiedza dotycząca biznesu znajduje się w jednym miejscu - oczywiście w przypadku monolitu tej wiedzy jest dużo, i myślę że jednym z powodów przejścia na mikroserwisy było właśnie to.

Jednakże dziś mamy świat zorientowany na usługi, więc pytanie brzmi : czy można coś zrobić aby wiedza o logice biznesowej serwisu nie była rozproszona pomiędzy wieloma zespołami?

Kierunek - Webcomponenty

Podkreślam - moim zdaniem - webcomponenty to kierunek do którego będą dążyć wszystkie dojrzałe i dużej skali systemy. Z tego co mi wiadomo tacy giganci jak Amazon, czy Google już z tego korzystają - zapewne kwestią czasu jest rozpowszechnienie się tego pomysłu.

Webcomponenty nie są czymś nowym, wyłoniły się w roku 2011, a z kolei w 2013 powstał Polymer na nich bazujący. Współczesne przeglądarki również zaczęły je sensownie wspierać. Sprawdź to tutaj webcomponents support

Webcomponenty - no ale co to?

Osobiście robiąc aplikacje mobilne, bardzo naturalną rzeczą było tworzenie kontrolek na poszczególne funkcjonalności. Przykładowo kontrolka do logowania się użytkownika, do wyświetlania jakiegoś czadowego wykresu - chodziło o to żeby można było bardzo łatwo ich używać w różnych miejscach aplikacji.

Webcomonenty można traktować dość podobnie. To taki zamknięty bloczek w formie pliku .js po zaimportowaniu którego mamy dodatkowe tagi html. Chodzi o dążenie do tego typu struktury: knowledge at microfrontends

Rozproszony frontend

Nie znam historii, ale myślę że kiedyś programiści backendu nie zajmowali się szczególnie wdrożeniami - choć też zapewne zależało to od miejsca pracy. Obecnie w zespołach coraz częściej mamy osobę nazywaną DevOps - chociaż to nieco błędne sformułowanie 🙂 Dążę do tego że kompetencje zespołu programistycznego uległy zmianie i potrzebę takiej zmiany widzę i tutaj. Po prostu team jako całość powinien być full stack.

Wyobraźmy sobie teraz zespół składający się z pięciu osób z czego dwie zajmują się tylko backendem, dwie tylko frontendem i mamy jedną osobę odpowiedzialną za wdrożenia - w praktyce te kompetencje będą nieco bardziej rozmyte, ale to nieistotne.

Skoro mamy już taki zespół, wyobraźmy sobie że dostają zadanie wykonania mikroserwisu odpowiedzialnego za zwracanie listy artykułów z wielu blogów, przetwarzanie ich i zapisywanie w swojej bazie. Wiedzą mniej więcej jakie są wymagania. Część backendowa zespołu zabiera się za pracę, opracowanie odpowiedniego modułu komunikacyjnego i tak dalej, z kolei osoby odpowiedzialne za frontend już myślą nad tym jakich informacji potrzebują i jak je chcą wyświetlić. Przygotowują sobie koncepcję endpointów których potrzebują, konsultują ją z resztą zespołu - dochodzą do ustalenia kontraktu.
Mogą od razu zacząć pracę, przygotowując sobie odpowiednie stuby. Front przygotowuje webcomponenty obsługujące te stuby. Jednocześnie powstaje już jakaś implementacja backendu, sprawdzają czy jakaś dodatkowa integracja jest potrzebna - robią poprawki.
Wersja 1.0 serwisu zawiera początkową implementację backendu i w prawie gotowy komponent graficzny udostępniany również przez serwis. DevOps wdraża te dwie rzeczy jako jedną paczkę, obraz dockera czy vagranta - nieważne.

Agregacja

No okej, ale brakuje nam czegoś. Brakuje miejsca gdzie backend i webcomponent zostaną wykorzystane. Stanie się to na warstwie UI, odpowiedzialnej jedynie za ściągnięcie komponentu z serwisu oraz ewentualne zarządzanie sesją użytkowika, routingiem pomiędzy podstronami - minimum logiki.

Kontrakty

Skoro agregacja zadziała się na warstwie UI to staje się oczywiste, że potrzebne są jakieś dodatkowe rzeczy związane integracją. Przykładowo można zastosować event bus w przeglądarce i pewne zdarzenia będę interpretowane przez warstwę szkieletową. Frontendzi muszą się tutaj dogadać.
Nie tylko o samym działaniu aplikacji rozmawiamy, ale też o jej wyglądzie i zachowaniu. Powinna być spójna, a webcomponenty tego nie ułatwiają, są oddzielone. Tu pojawia się dylemat - podlinkować CSSy, duplikować? Jedno jest pewne, w ramach aplikacji należy zdefiniować design system i się do niego stosować.

Wielkie frameworki

Separacja, niezależność - tylko co z używanymi frameworkami? Zespoły mogą mieć różne preferencje, jedni wolą używać Angular, inni Vue. Jest to możliwe z wykorzystaniem webcomponentów. Nie wiążemy się na stałe z jednym frameworkiem. Pamiętacie AngularJS? W typowym podejściu przepisać trzeba niemal cały frontend aby się go pozbyć. Tutaj moglibyśmy przepisywać pojedyńcze komponenty, i fragmenty UI - podobnie jak w przypadku mikroserwisów. Jeśli zastanawiacie się jak wasz ulubiony framework współpracuje z webcomponentami, proponuję zajrzeć tutaj.

Podsumowanie

Mikroserwisy wprowadziły w życie developerów szereg problemów do rozwiązania - co generuje również dodatkowe koszta. Mikrofrontendy są bardzo podobne. Czy warto?

microfrontends vs microservices

Moim zdaniem nie warto brnąć w tego typu pomysły bez wyraźnej potrzeby. Podobnie w przypadku backendu. Architektura to proces - myślę że należy pozwolić na taki rozwój aplikacji aby funkcjonalności wdrażać możliwie szybko co nie sprzyja ani mikroserwisom, ani mikrofrontendom. Podobnie jak w przypadku backendu, tak samo przemyślana struktura aplikacji frontendowej pozwoli na migrację w kierunku tego pomysłu - kiedy zajdzie taka potrzeba. Podoba mi się bardzo tzw. Strangler pattern - niby oczywista oczywistość, ale od razu wiadomo o co chodzi.

Na ten wpis to by było na tyle. W kolejnym zamierzam przedstawić działającą aplikację zgodnie z tą ideą i jej kluczowe fragmenty. Zachęcam do komentowania 🙂

Close Menu