Hapi.js – Wprowadzenie

Po moich dwóch poprzednich wpisach dotyczących frameworka hapi.js na platformę Node.js, wiele osób zaczęło zadawać mi różne pytania. Poniżej zebrałem najciekawsze z nich oraz kilka własnych przemyśleń. Należy potraktować to jako miękkie wprowadzenie do tworzenia backendu w Node.js z hapi.js.

Skąd się w ogóle wzięło hapi.js?

Hapi.js jest frameworkiem JS przeznaczonym na platformę Node.js. Zaczął powstawać w 2011 roku i niemal od początku był silnie wspierany i wykorzystywany przez zespół developerów z Walmart. Nazwa frameworka wzięła się od skrócenia zwrotu “HTTP API”.

Projekt był rozwijany jako Open Source na GitHubie, a po dłuższym czasiem stał się zupełnie niezależny od Walmarta. Można powiedzieć, że inwestycja się opłaciła – Walmart nadal korzysta ze wspaniałego narzędzia, któremu dał początek, a które teraz dzięki swojej popularności rozwijane jest przez społeczność.

Hapi.js obsługiwał cały ruch z urządzeń mobilnych na Walmart.com już w 2013 roku. Było to wtedy prawdopodobnie największe wdrożenie aplikacji opartej o Node.js w ogóle. W czasie Black Friday 2013 twórcy hapi.js dzielili się relacjami na temat wydajności Node.js i hapi.js na Twitterze pod hashtagiem #nodebf. Okazało się, że framwork spisał się lepiej niż wyśmienicie. Cały ruch (a jego rozmiar jest dla mnie praktycznie niewyobrażalny) mógłby zostać obsłużony na 10 rdzeniach i 28GB pamięci RAM – czyli stosunkowo słabej mocy serwerze.

Hapi.js jest wykorzystywany przez m.in. Yahoo, Disney, PayPal, GOV.UK, Mozilla, npm, czy Hoodie, a także wiele innych dużych firm. W tej chwili framework ma 7310 gwiazdek na GitHubie.

Jakie są cele i założenia hapi.js?

Wymieniam dwa główne założenia projektu:

Testy

Jednym z założeń hapi jest jego testowalność. Framework udostępnia pomocniczną metodę (server.inject(…)) służącą do testowania pluginów i endpointów. Warto zauważyć, że pokrycie kodu hapi.js testami wynosi 100% – jest to jeden z celów twórców hapi.

Modularna architektura

Architektura hapi.js różni się od większości frameworków i bibliotek dostępnych na rynku. Hapi chce być pełno-funkcjonalnym framworkiem, dającym ogromne możliwości. Podobny cel stawia sobie wiele innych frameworków i mikroframeworków, jednak robią to na różne sposoby. Z grubsza, możemy podzielić je na trzy grupy.

Pierwsza to rozbudowane i bardzo „zopiniowane” rozwiązania. Nazwijmy je tutaj „monolitycznymi”. Doskonałym przykładem takiego monolitu jest choćby Sails.js – framework o sporych możliwościach, jednak w którym twórcy poczynili szereg założeń i narzucają programistom wiele konwencji.

Przeciwwagą dla takiego rozwiązania są mikroframeworki i biblioteki takie jak Express.js. Ich zaletą bez wątpienia jest ogromna elastyczność, jednak wymagają podejmowania wielu decyzji odnośnie struktury i architektury aplikacji, a także integrowania kodu z wieloma modułami stron trzecich.

Zespół hapi.js podchodzi do tego tematu inaczej i stawia na rozwój silnego „rdzenia” frameworka oraz licznych oficjalnych i nieoficjalnych pluginów rozszerzających jego możliwości. Samo hapi.js jest bazą do tworzenia aplikacji internetowych i udostępnia sporo różnych funkcji związanych z tworzeniem serwera, połączeń, obsługą HTTP i serwowaniem treści. Wszelkie dodatkowe opcje, takie jak uwierzetelnianie czy obsługia ciastek są dodawane poprzez rozbudowany system pluginów.

Dodatkowo warto zwrócić uwagę, że hapi.js nie czyni żadnych założeń co do struktury kodu programisty. Używając hapi.js możesz stworzyć monolit, albo całkowicie luźno powiązane moduły. HapiJS może posłużyć do serwowania statycznego HTML-a, albo baza pod microservice’y. Możesz dowolnie ułożyć pliki i foldery, i korzystać z dowolnej konwencji.

Konfiguracja jest najważniejsza

Twórcy Hapi.js mocno postawili na realizowanie podejścia configuration-centric. W praktyce oznacza to, że zamiast wywoływać kolejne metody udostępnione przez hapi, w większości przypadków przekazujemy po prostu obiekt z konfiguracją, którą hapi obsługuje. Jakie są zalety tego rozwiązania? Skupiamy się na deklarowaniu konfiguracji, a nie na poznawaniu metod konkretnego frameworka. Dodatkowo, obiekty z konfiguracją możemy przenieść do osobnego pliku .js czy nawet .json, a następnie bez problemu wykorzystać w innym miejscu.

Przykładowo, w projekcie nad którym pracowałem, każdy endpoint składał się przynajmniej z 3 niezależnych plików: handlera, walidacji i route’ów, przy czym te dwa ostatnie były niczym więcej niż wyeksportowanymi prostymi obiektami JS. Takie podejście pomaga zachować porządek w kodzie oraz przyspiesza proces powstawania aplikacji. Ponadto, ułatwia także czytelność – chcąc znaleźć opis walidacji danego endpointa nie musiałem w ogóle zaglądać do kodu handlera.

Co więcej, twórcy hapi zadbali o to, aby framework automatycznie uzupełniał brakujące informacje sensownymi wartościami domyślnymi. Na przykład, jeśli dany endpoint zwraca tekst, to typ odpowiedzi automatycznie zostanie ustawiony na text/plain, jeśli zaś zwrócimy obiekt, to zostanie on zamieniony na JSON i zwrócony jako application/json. Dzięki temu w wielu przypadkach sporą część konfiguracji możemy skrócić lub w ogóle pominąć.

Do czego nadaje się hapi.js

Hapi jest frameworkiem, który można wykorzystać do wielu celów na wiele różnych sposobów. Hapi świetnie nada się między innymi do:

  • tworzenie REST API (JSON, XML)
  • serwowanie statycznego HTML-a,
  • renderowanie szablonów (np. Handlebars czy Jade),
  • tworzenie proxy (przez plugin h2o2 – w ten sposób Walmart przekierowywał żądania do starych legacy serwisów napisanych w Javie zanim zostały w całości zastąpione Node.js)
  • serwowanie front-endu i backendu do Single Page Applications (React, Angular)
  • jako front controller do innych aplikacji, np. symulacji fizycznych napisanych w C++

Gdzie szukać pomocy z hapi.js?

Przede wszystkim warto zajrzeć na stronę hapi. Jest tam cała dokumentacja API frameworka, tutoriale i materiały: https://hapijs.com/

Błędy można zgłaszać na GitHubie. Najpierw jednak warto poszukać, czy podobny problem nie został już zgłoszony 🙂 https://github.com/hapijs/hapi

Jest też kanał hapijs/hapi na Gitterze: https://gitter.im/hapijs/hapi

Oraz kanał #hapi na freenode (IRC): http://webchat.freenode.net/?channels=hapi

Na StackOverflow istnieje specjalny tag hapijs pod którym można szukać i zadawać pytania związane z tym frameworkiem: http://stackoverflow.com/questions/tagged/hapijs

Więcej pomocnych informacji można znaleźć na https://hapijs.com/help