Generyczne API lub Back-End na potrzeby Front-End? Możesz mieć i to i to.

Konsumenci API

Aplikacje webowe

Nowoczesne frameworki webowe interfejsu użytkownika, takie jak React, Vue czy Angular są de facto autonomicznymi i bogatymi aplikacjami JavaScript działającymi w środowisku przeglądarki. Wysyłają one żądania do interfejsów programistycznych aplikacji (API) w celu generowania i aktualizacji widoków oraz reagowania na zdarzenia w ramach interfejsu użytkownika (UI) poprzez wywoływanie command API służących modyfikacji stanu procesów biznesowych i danych.

Nowoczesne zaawansowane aplikacje wykorzystują czas działania przeglądarki, korzystając z lokalnych zasobów, umożliwiając bardziej efektywne wykorzystanie sieci, a nawet dają możliwość pracy w trybie offline.

Aplikacje mobilne

Aplikacje na Androida i iOS na telefony, tablety i urządzenia bardzo często mają inne interfejsy użytkownika (UI) niż strony internetowe i są zoptymalizowane na potrzeby urządzeń mobilnych. Na przykład, aplikacje bankowe zazwyczaj po uruchomieniu dostarczają prostych informacji o domyślnym koncie, a następnie udostępniają opcje wykonywania różnych operacji na koncie, podczas gdy aplikacje internetowe witają użytkowników, prezentując im „na dzień dobry” większą ilość informacji na temat ich kont i innych usług finansowych oferowanych przez bank. Komunikują się również z API, aby uzyskać te informacje, ale w różnych formach i przy użyciu różnych wzorców rozmowy.

Inteligentne urządzenia

Inteligentne głośniki, aplikacje samochodowe i niezliczona ilość innych połączonych z Internetem urządzeń również ma na celu wzbogacić doświadczenie użytkownika i w tym celu muszą korzystać z interfejsów API.

Inni konsumenci API

Stanowią często największą grupę konsumentów i znajdują się w dużych przedsiębiorstwach, w których dostęp do API mają korporacyjni brokerzy API, korzystający z kolejek i proxy. API może być używane do wykrywania zmian stanu (pooling), publikowania i odbierania zdarzeń biznesowych na szynie aplikacji lub usług. Wywołania API mogą wykorzystywać podejścia orkiestracji lub choreografii. Możemy uzyskać bezpośrednie wywołania HTTP poprzez użycie wzorców pub/sub ze szkieletem wiadomości.

Generyczne API

Generyczne API jest uniwersalne i próbuje zaspokoić potrzeby każdego konsumenta. Dobry projekt jest zgodny z Domain Driven Design i stara się przewidywać procesy biznesowe i przypadki użycia, które przekształcają się w komunikację pomiędzy różnymi API.

Generyczne API nie jest świadome istnienia swoich konsumentów, co jest pozytywne z punktu widzenia kierunku zależności.

Zalety

Jest to również świetne rozwiązanie, jeśli chodzi o rozdzielenie odpowiedzialności. Konsumenci API polegają na API generycznym, na które nie ma wpływu to, w jaki sposób i jaki konsument z niego korzysta. Inny klient może połączyć się z API kolejnego dnia, co nie będzie wymagało wprowadzenia żadnych zmian w API.

Wady

Jeśli jedno rozwiązanie ma spełniać wszystkie potrzeby, to zazwyczaj oznacza, że nie jest zoptymalizowane pod kątem żadnej z nich. Wielu klientom może nie podobać się konieczność zbyt wielu wywołań API w celu spełnienia ich wymagań w ramach UI.

Istotne jest, aby wyjaśnić to bardziej szczegółowo, więc posłużę się przykładami.

Wyobraźmy sobie prostą aplikację bankową na smartwatcha. Jej działanie ogranicza się zasadniczo do wyświetlania stanu środków na domyślnym koncie bankowym. Generyczne API wraca z informacją o liście kont wraz z ich danymi (które nie są wymagane przez aplikację zegarkową), następnie konsument musi ponownie wywołać API, aby uzyskać szczegółowe informacje o koncie, w tym zobaczyć aktualny stan środków. Jak widać, zamiast jednego wywołania, które dostarczy konkretnej informacji liczbowej, musimy wykonać dwa wywołania, dzięki którym uzyskujemy 90% danych, których nie potrzebujemy w przypadku naszego klienta.

Innym przykładem jest sytuacja odwrotna. API zwraca podzbiory danych, których potrzebujemy na formularzu dla użytkownika i musimy wykonać wywołanie API dla listy pozycji (jak transakcje bankowe, aby uzyskać ich ID), a następnie dziesiątki lub setki wywołań, aby uzyskać szczegółowe informacje dla każdego z nich; w rezultacie mamy do czynienia z dużym opóźnieniem, a użytkownik musi czekać.

Jest to typowe dla tzw. fasad baz danych; otrzymujesz listę identyfikatorów, a następnie wywołujesz inne API dziesiątki lub setki razy, aby uzyskać potrzebne dane.

Ale tak to jest, jeśli staramy się spełnić oczekiwania wszystkich.

Pamiętaj – nie wolno nam nic zmieniać w generycznym, korporacyjnym API. Architekci API nie chcą niczego popsuć, ponieważ potrzebują stabilności i muszą zachować ostrożność. Z technicznego punktu widzenia takie podejście działa. Nie jest skuteczne, ale działa.

API specyficzne dla klienta (backend for frontend – BFF)

Zgodnie z tym podejściem każdy klient ma swoje własne API, które dokładnie odpowiada jego potrzebom, więc mamy wiele API dla wielu aplikacji klienckich.

Zalety

Klient dostaje dokładnie to, czego chce za pomocą pojedynczych wywołań API (zwykle na ekranie lub jako fragment UI); opóźnienie jest małe (pojedyncze wywołanie), a wykorzystanie pasma danych również jest optymalne (dokładnie to, czego potrzebujemy na potrzeby UI, nie za dużo, nie za mało).

Wady

API jest specyficzne dla bieżącego przepływu UI, ale nie jest odpowiednie dla innych klientów. Odwołując się do naszych przykładów, dobrze nadaje się do przeglądarek w komputerach stacjonarnych, ale już nie najlepiej spisuje się w przypadku aplikacji mobilnych.

Liczba API dla klientów jest często niedoszacowana; na przykład, jedno API dla aplikacji webowych, jedno dla smartfonów i jedno dla zegarka.

Nieważne, czy zmiana logiki biznesowej dotyczy ogólnego API, czy BFF – muszą one zostać zmodyfikowane.

Możesz mieć i to i to → couper.io

Istnienie zarówno generycznego API, jak i BFF jest uzasadnione i oba rozwiązania mają sens. Czyż nie? Czy jest jakiś sposób na skorzystanie z obu rozwiązań?

Wyobraź sobie pracę z ekosystemem aplikacji dużego przedsiębiorstwa z setkami aplikacji biznesowych i konsumentów API, wraz z silnym nadzorem zespołów odpowiedzialnych za API, ale niechętnym do wprowadzania zmian w celu zachowania stabilności API.

Nadal możesz stworzyć backend dla swojego front-endu. Jak? Wiele problemów na etapie projektowania oprogramowania może być i jest rozwiązanych poprzez dodanie kolejnej warstwy abstrakcji.

Generyczne API może być połączone z usługą backendową, która będzie działać jako proxy dla adaptera API i tworzyć specyficzne dla klienta API. Avenga’s Couper.IO może Ci w tym pomóc.

Możesz pobrać narzędzia ze strony internetowej produktu, zdefiniować mapowania i tłumaczenia pomiędzy generycznymi API, których nie możesz zmieniać, aby utworzyć swoje specyficzne BFF API odpowiadające potrzebom Twojej aplikacji front-endowej.

Ale nie martw się. To nie jest kolejny potworny silnik. Jest szybki i sprawdzony w rzeczywistych projektach łączących setki nowoczesnych, nieco mniej nowoczesnych i starszych API z doskonałym UX-em, który jest wymagany.

Kilka słów podsumowania

W dyskusji na temat zalet API generycznego i uniwersalnego, potrzeb nowoczesnego UX, który oczekuje specyficznego BFF, nie powinniśmy zapominać, że możemy mieć i to i to. Dzięki inteligentnemu projektowi architektonicznemu wspieranemu przez odpowiedni produkt, może on być stosunkowo łatwy do zrealizowania. Pozwala to na tworzenie nowoczesnych doświadczeń użytkownika przy jednoczesnym zachowaniu istniejących (generycznych) API, a tym samym przyspieszenie transformacji cyfrowej.

Powrót do przeglądu