16 lutego 2022

Nowe rozwiązania w projekcie innowacyjnej platformy bankowej dla Vodeno  

To już ponad trzy lata, odkąd jestem częścią niezwykłego przedsięwzięcia, które realizujemy razem z Vodeno. Cały ten okres przynosił coraz to nowsze wyzwania i co za tym idzie, możliwość tworzenia ciekawych rozwiązań dla obszaru usług technologiczno-finansowych. Pozwolę sobie opisać kilka z nich.

Mikroserwisy na front-endzie

Pierwszym z nich było zaprojektowanie architektury warstwy front-end. Głównym wymaganiem było, aby poszczególne moduły aplikacji mogły być w pełni rozwijane przez niezależne zespoły deweloperskie, co a z tym idzie – tworzone w oparciu o dowolny framework bądź bibliotekę oraz wydawane niezależnie. Od razu nasunął nam się termin znany w świecie back-end – mikroserwisy. Architektura oparta o mikroserwisy była nam dobrze znana. Na rynku istniało już dużo aplikacji, frameworków, bibliotek wpierających ten model, ale i też olbrzymia liczba publikacji stworzonych na bazie doświadczenia, mówiących o tym, jak pisać i – co ważniejsze – czego unikać, by nie popełnić pewnych błędów. Było jednak jedno „ale” – większość rozwiązań, które mogłyby się pochwalić książkową implementacją tej architektury w warstwie back-end wciąż posiadało jeden front-end realizujący szereg często oddzielnych domenowo usług. Owszem, istniały już rozwiązania dla weba w postaci monorepo lub łączenia poszczególnych modułów rozwijanych jako „biblioteki” podczas budowania aplikacji, ale nie spełniały one kryterium albo niezależnego tworzenia, albo wydawania funkcjonalności. Wykorzystując nasze duże doświadczenie na tym polu, musieliśmy zrealizować ten pomysł „na froncie”. Było to nie lada wyzwanie. Tworząc i testując różne proof of concept, zdecydowaliśmy się wybrać single-spa – framework, który określany jest jako „top level router” dla mikroserwisów front-end. Każdy moduł mógł być autonomiczną, wydawaną oddzielnie SPA, developowaną w oparciu o dowolny framework bądź bibliotekę.

Kolejnym naszym celem było, aby przyszłe front-endowe mikroserwisy tworzyły spójną całość zgodną z wysokimi standardami UX. Aplikacja miała być projektowana w oparciu o podejście mobile first. Chcieliśmy również, aby projekty realizowane przez zespoły oparte były o wspólne standardy, dobre praktyki oraz możliwość wymiany wiedzy i doświadczeń. Te czynniki sprawiły, że wybraliśmy React jako wiodącą bibliotekę. Pozwala ona na tworzenie reużywanych komponentów, jest szybka, skalowalna i prosta. Posiada również ogromną społeczność. Moduły miały mieć spójny UI/UX, dlatego wymagane było stworzenie wspólnej biblioteki komponentów.

Od każdej aplikacji webowej, zwłaszcza serwowanej na urządzenia mobilne, wymaga się, aby była lekka, responsywna i aby „time to first byte” był jak najmniejszy. Przed nami pojawił się kolejny challenge – optymalizacja. 🙂 Na etapie, na którym się znajdowaliśmy, każdy z modułów w swoim bundle’u zawierał własną instancję zależności, które wykorzystywane były przez inne serwisy, np. React czy współdzielone biblioteki. Taka sytuacja powodowała, że nawigując po aplikacji, pobierany był redundantny kod. Ten temat często był poruszany na konferencjach czy meetupach i przeważnie kwitowany był wnioskiem, że jest to jedna z konsekwencji architektury mikroserwisów. Dlaczego by nie umożliwić modułom „korzystania” w runtime np. z jednej instancji Reacta? Zaproponowaliśmy i wdrożyliśmy rozwiązanie, w którym mikroserwisy mogły w deklaratywny sposób definiować, które zależności wykluczyć z bundle’a  i oczekiwać ich wstrzyknięcia w czasie życia aplikacji.

Pozostał ostatni temat – komunikacja pomiędzy modułami. Jeden moduł miał nawigować do drugiego w celu realizacji konkretnego scenariusza biznesowego np. przejście ze szczegółów rachunku do formularza przelewu. Załóżmy, że moduł rachunków oraz przelewów to dwa niezależne serwisy będące SPA. Każdy dostarcza szereg funkcjonalności np.: zarządzanie rachunkiem, historia transakcji, przelewy zewnętrzne czy pomiędzy swoimi rachunkami. Każdy ma własny wewnętrzny routing. Osadzanie na sztywno adresów nie wchodziło w grę – spowodowałoby to zbyt silne powiązania i zależności. Przecież podczas rozwoju aplikacji zespół może zdecydować o zmianie w routingu. Dodatkowo moduły mogłyby być inicjalizowane z danymi wejściowymi np. obciążanym rachunkiem domyślnym do przelewu. Rozwiązanie znaleźliśmy, wzorując się na mechanizmie intentów, znanym twórcom aplikacji mobilnych na Android.

Opisane powyżej rozwiązania stworzyły spójną całość będącą architekturą warstwy front-end systemu, w którego budowaniu mieliśmy udział.

CI/CD

Sam stos technologiczny aplikacji to jedno. Potrzebny był proces CI/CD, który miał wspierać deweloperów, aby dzieło ich pracy spełniało jak najlepsze standardy, miało jak najmniej podatności oraz znajdowało się na środowiskach w możliwie najszybszym czasie.

Zarządzanie repozytoriami  oparto o platformę GitLab, która jest obecnie narzędziem wspierającym nie tylko sam proces developmentu i wersjonowania kodu, ale całościową platformą DevOps, która poprzez oferowane narzędzia tworzenia, weryfikacji, releasowania i deploymentu aplikacji pozwala w szybki i transparenty sposób dostarczać nowe funkcjonalności na środowiska.

Git jako system kontroli wersji daje bardzo dużą swobodę, dlatego sam workflow wzoruje się na Gitlab Flow. Deweloperzy tworzą poszczególne funkcjonalności w oddzielnych gałęziach. Po skończeniu pracy tworzą tzw. „merge request”, na którym odbywa się review oddanej pracy. Dzięki GitLab pipeline nowy kod może zostać poddany testom zarówno jednostkowym, jak i e2e. Dodatkowo kod zostaje sprawdzany pod kątem jakościowym oraz podatności na zagrożenia. Po dołączeniu zmian do gałęzi głównej wydawana jest nowa wersja aplikacji gotowa na wdrożenie na kolejnych środowiskach, by ostatecznie znaleźć się na środowisku produkcyjnym.

Jak wiadomo, architektura oparta o mikroserwisy implikuje fakt, że poszczególne aplikacje się ze sobą komunikują. W niektórych przypadkach zautomatyzowanie i utrzymanie testów e2e może przynosić więcej nakładu prac i mniej korzyści. Rozwiązanie znaleźliśmy w pact.io. Jest to narzędzie, które umożliwia testowanie spójności komunikatów wymienianych pomiędzy kolejnymi wersjami aplikacji za pomocą testów kontraktów. Testy te zapewniają, że wymieniane komunikaty są zgodne ze wspólnym zrozumieniem udokumentowanym w kontrakcie.

Wspólna praca nad całością pozwoliła zdefiniować standardy i dobre praktyki dla tworzonych projektów, które oczywiście są nadal rozwijane. Każdy ma różne doświadczenia, dlatego nieodzowną częścią tego procesu jest ich konfrontacja tak, aby razem wypracować rozwiązania.

Płatności nie takie zwykłe

Po pracach koncepcyjnych i projektowaniu technicznych części systemu, które w dalszym ciągu są rozwijane są na bieżąco, przyszedł czas na rozwój funkcjonalności biznesowych. Dostaliśmy z zespołem za cel realizację modułu płatności.

Brałem już udział w projektach tworzących rozwiązania dla bankowości internetowej, szczególnie takie funkcjonalności, które odpowiadają za realizację przelewów. Temat wydawał mi się więc znany i rozpracowany. Był to tzn. bankowy standard – kilka formularzy przelewów (m.in.: krajowy, wewnętrzny, zagraniczny SWIFT oraz SEPA), zlecenia stałe, przelewy odroczone, szablony płatności. Okazało się jednak, że nie było to nic z tych rzeczy. 🙂 Nie mieliśmy powielać obecnych schematów, a wdrożyć coś nowego. W tradycyjnych bankowościach klient najpierw musi wybrać typ przelewu, co sprowadza się do tego, że musi on wiedzieć, jakim kanałem przelew ma być wysłany, zanim zacznie wprowadzać dane przelewu. Może to być dla klienta kłopotliwe, np. chce on wysłać przelew za granicę – co ma wybrać? Przelew SEPA? SWIFT? Wybiera SWIFT, podaje rachunek odbiorcy, jego dane, kwotę i walutę w EUR. Nagle pojawia się komunikat, że dane przelewu pasują do schematu przelewu SEPA (okazało się, że rachunek odbiorcy należy do banku w strefie SEPA) – i co teraz? Czym jest SEPA, a czym SWFT? To tylko jeden z wielu przykładów.

W tym projekcie podejście, jakie chcieliśmy i dalej chcemy rozwijać, jest inne – klient definiuje potrzebę, tj. określa, co chce zrobić, a zadaniem systemu jest poprowadzenie go i jak najlepsza realizacja płatności. Na przykład na podstawie danych odbiorcy i przelewu wybierany jest najlepszy dla klienta kanał, którym płatność będzie procesowana. W naszych wdrożeniach inne jest również podejście do definiowania odbiorców oraz autoryzacji płatności. Tworzenie odbiorcy kończy się procesem autoryzacji, przez co odbiorcy są „zaufani” i wysłanie do nich przelewów autoryzacji już nie wymaga. Sami odbiorcy w systemie mogą mieć po kilka numerów rachunków, a model zarządzania nimi przypomina zarządzanie książką kontaktów.

Oczywiście opisałem tu tylko część funkcjonalności, jakie dostarcza moduł płatności, który pozwala na konfigurację wspomnianych flow w zależności od potrzeb klienta.

Na koniec

Praca nad tym projektem opiewa w coraz to ciekawsze i wymagające wyzwania, które chętnie podejmujemy motywowani pokonywaniem poprzednich. Jak wspomniałem wcześniej, każdy ma swoje doświadczenia. Bardzo dobrze wspominam dyskusje i brainstormingi, na których opracowujemy rozwiązania, które często wymagają opuszczenia swojej strefy komfortu i poszukania czegoś nowego. Wymagania są wysokie, ponieważ sama domena produktu jest bardzo złożona i dodatkowo obarczona restrykcjami czy regulacjami prawnymi. Poprzeczkę stawiamy sobie wysoko, ponieważ korzystanie z rezultatów naszych prac musi budzić zaufanie klienta, który powierza nam zarządzanie swoimi środkami. Dzięki temu poszerzamy swoje horyzonty zarówno w zakresie wiedzy domenowej, jak i technologicznej. Wciąż szukamy czegoś nowego. Oprócz rozwoju, wiedzy i zdobywania kolejnych doświadczeń daje nam to dużą satysfakcję, która jeszcze bardziej nas nakręca, ponieważ jesteśmy zakręceni na punkcie IT… i chcemy wciąż więcej. 🙂

Rafał Kolecki – Developlement Team Leader / Architekt w Onwelo, fan ciekawych i nieszablonowych rozwiązań, zainteresowany technologią, sportami wodnymi oraz piwowarstwem domowym

Zostaw komentarz

Polecamy

Strategie migracji do chmury

Strategie migracji do chmury

Istnieje kilka sprawdzonych metod migracji do chmury. Firma Gartner zdefiniowała tzw. zasadę 5 R strategii migracji do chmury, którą można rozwinąć jako: Rehost, Refactor, Replatform, Rebuild i Replace.

Strategie migracji do chmury

Strategie migracji do chmury

Istnieje kilka sprawdzonych metod migracji do chmury. Firma Gartner zdefiniowała tzw. zasadę 5 R strategii migracji do chmury, którą można rozwinąć jako: Rehost, Refactor, Replatform, Rebuild i Replace.

#Udostępnij

strzałka przewiń do góry strony