W 2018 roku trudno wyobrazić sobie programistę webowego, który nie słyszał, chociażby mimochodem, o Amazon Web Services. Wiedzeni szumem środowiskowych szeptów na temat chmury i serverless z ciekawości logujemy się do konsoli AWSa i często jest to dosyć bolesne starcie z rzeczywistością, bo pierwszy kontakt z chmurą Amazona może być nieco przytłaczający. Zanim zaczniemy korzystać z dostępnych usług zapoznać musimy się z szeregiem specyficznych dla chmury pojęć i technologii takich jak: roles, permissions, IAM, ARN, VPC etc. Oczywiście od dawna dostępne są technologie ułatwiające i usprawniające pracę (np. Serverless Framework czy SAM), ale nie eliminują one konieczności znajomości zasad działania chmury na poziomie infrastruktury.


Jakub Holak. Lead Front End Developer w dziale R&D firmy Nordcloud — firmie specjalizującej się w wykorzystaniu AWS, Microsoft Azure i Google Cloud Platform. Javascriptowy geek, entuzjasta platformy web i oprogramowania open source. Bywa prelegentem na konferencjach i meetupach. Po godzinach pracy ojciec, mąż, biegacz amator i muzyk.


Jeśli Wasze pierwsze zetknięcie z AWS było równie trudne, lub jeśli po prostu chcecie eksperymentować z chmurą szybko i łatwo, w sierpniu tego roku pojawił się zestaw narzędzi wiersza poleceń pod nazwą Amplify CLI Toolchain, który wydaje się być odpowiedzią na te problemy — architektura typu serverless zdejmuje z nas konieczność przejmowania się serwerami i konfiguracją, a Amplify zdejmuje z nas obowiązek konfiguracji usług w chmurze i ich zależności i relacji.

Pod nazwą AWS Amplify pierwotnie (od 2017 roku) dostępna była frontendowa biblioteka javascriptowa, która zawiera szereg funkcjonalności ułatwiających pracę z chmurą. Biblioteka ta jest abstrakcją na AWS SDK, które jest stosunkowo niskopoziomowe — na przykład dostępna w ramach chmury Amazona usługa Cognito, która służy do autoryzacji, uwierzytelniania i kontroli dostępu wymaga odświeżenia tokenów co godzinę — korzystając z SDK musielibyśmy samemu zadbać o odświeżenie tokenu przed upłynięciem terminu jego ważności. Jeśli skorzystamy z Amplify nie musimy nawet wiedzieć o istnieniu tych tokenów — wszystkim zajmie się biblioteka, a my korzystać będziemy z niej za pomocą metod typu signIn() czy currentAuthenticatedUser(). Przykłady tego typu udogodnień mógłbym wymieniać do końca artykułu.

Oprócz samej biblioteki dostaliśmy też szereg komponentów ułatwiających integrację z popularnymi frontendowymi frameworkami. W przypadku Reacta jest to zestaw Higher Order Components, który sprawia, że zarządzanie uwierzytelnianiem w naszej aplikacji sprowadza się do opakowania naszego głównego komponentu za pomocą funkcji withAuthentication().

JSowa biblioteka jest dużym udogodnieniem przy tworzeniu interfejsu użytkownika (webowego lub React Native), jednak nie ma wpływu na konfigurację usług w chmurze. W sierpniu 2018 roku Amazon udostępnił Amplify CLI Toolchain — narzędzie pozwalające na tworzenie i konfigurację usług w chmurze bez wysiłku i konieczności znajomości meandrów chmury Amazona — wszystkie wymagane od nas akcje wykonamy z poziomu wiersza poleceń, z folderu naszej frontendowej aplikacji.

W tym miejscu mógłbym wymienić dostępne w ramach tego CLI usługi i powiedzieć o nich nieco więcej, jednak wydaje mi się, że użyteczność tego narzędzia najlepiej pokazać na przykładzie, zwłaszcza, że informacje dotyczące wszystkich dostępnych w Amplify usług łatwo znajdziecie na stronie aws-amplify.github.io.

Zbudujmy coś w chmurze

Chciałbym pokazać Wam krok po kroku jak przy pomocy CLI i wspomnianej biblioteki frontendowej możemy szybko stworzyć aplikacje typu real time. Nie opuszczając katalogu z naszym reactowym kodem, w prosty sposób stworzymy w pełni funkcjonalną aplikację, w której dostępna będzie funkcjonalność chatroomu z automatycznym wyświetlaniem nowych wiadomości, z której korzystać będzie mógł każdy po zarejestrowaniu się i zalogowaniu w naszej aplikacji. Stworzenie gotowego do użycia backendu będzie wymagać kilku minut naszej pracy i kilku dodatkowych czekania na tworzenie zasobów w AWS!

Aby rozpocząć korzystanie z Amplify musimy zarejestrować konto na Amazon Web Services, stworzyć użytkownika i wygenerować klucze dostępu, przez większość tego procesu przeprowadzi nas Amplify. Na początek instalujemy CLI przy pomocy NPM npm install -g @aws-amplify/cli. Zanim przejdziemy do konfiguracji musimy posiadać konto w AWS — jeśli takowego nie mamy, musimy się zarejestrować. Następnie dokonamy konfiguracji nowo zainstalowanego CLI — proces uruchomimy wpisując polecenie amplify configure.

Na początek narzędzie poprosi nas o zalogowanie się w AWS w przeglądarce. W kolejnym kroku zostaniemy zapytani o region, w którym chcemy korzystać z usług Amazona (więcej o regionach znaleźć można tutaj). Wybieramy eu-west-1, który oznacza Irlandię. Kolejne pytania dotyczyć będą użytkownika, którego amplify stworzy w naszym AWSowym koncie. Dalej, ponownie w przeglądarce zostaniemy poproszeni o wypełnienie formularza (możemy po prostu kliknąć Next kilka razy) i wpisanie w wierszu poleceń wygenerowanych kluczy dostępu. W kolejnym kroku stworzymy profil AWS w naszym wierszu poleceń i to tyle — Amplify CLI jest gotowy do użycia.

Możemy przystąpić do tworzenia naszej aplikacji — zaczniemy od stworzenia czystej aplikacji opartej o Create React App – npx create-react-app chat. Po zainicjalizowaniu aplikacji w katalogu chat znajdziemy gotowy do użycia starter aplikacji. Do części frontendowej wrócimy za moment — najpierw stwórzmy backend naszego serwisu. Wewnątrz katalogu z CRA zajnicjalizujemy Amplify dla naszej aplikacji przy użyciu amplify init. Odpowiadamy na kilka pytań dotyczących naszego projektu i po chwili, w której Amplify tworzy zasoby potrzebne do inicjalizacji naszego projektu w chmurze możemy rozpoczynać pracę nad naszą aplikacją.

Amplify znakomicie współpracuje z usługą AWS AppSync, która umożliwia tworzenie API opartych o GraphQL ze wszystkimi zaletami tej technologii (jeśli nie zetknęliście się do tej pory z GraphQL to w dużym skrócie jest to stosunkowo nowy sposób tworzenia API, polegający na użyciu silnie typowanego języka zapytań wspólnego dla klienta i serwera). Jedną z bardzo ważnych, a często niedocenianych zalet GraphQLa jest możliwość tworzenia subskrypcji — w bardzo dużym uproszczeniu możemy umożliwić stronie serwera przesyłanie aktualizacji do klienta — w przypadku AppSync jest to możliwe dzięki użyciu protokołu MQTT via WebSocket.

Do uwierzytelnienia użyjemy innej usługi Amazona, wspomnianego wcześniej Cognito. Dane naszej aplikacji trzymać będziemy w bazie danych DynamoDB, ale o tym nie musimy nawet wiedzieć — zostanie dla nas stworzona przez Amplify. AppSync doskonale działa z DynamoDB — pozwala na automatyczne pobieranie i synchronizację danych z tej bazy danych. Pomiędzy naszym API i bazą nie potrzebujemy żadnego dodatkowego kodu, zarówno żeby wykonywać operacje CRUD jaki i korzystać z subskrypcji. Naszą frontendową aplikację opublikować możemy przy użyciu jednej z najstarszych usług AWS – S3.

Struktura naszej aplikacji wyglądać będzie tak jak na poniższym schemacie:

Jak widać centralnym punktem naszej aplikacji będzie wspomniany AppSync. Aby utworzyć i skonfigurować dowolną usługę przy pomocy Amplify wpisujemy polecenie amplify add nazwa_kategorii_usługi, np. amplify add api. Przy pomocy Amplify stworzyć możemy dwa rodzaje API — REST oparte o AWS API Gateway lub GraphQL — dziś interesuje nas to drugie. Wybieramy nazwę dla naszego API i w następnym kroku wybrać musimy rodzaj autoryzacji którego chcemy używać. W naszym przypadku będzie to Amazon Cognito User Pool, w standardowej i sugerowanej przez Amplify konfiguracji. Gdybyśmy wybrali opcję tworzenia własnej, moglibyśmy zdecydować o kilku aspektach dotyczących zbierania danych użytkowników, wymaganej sile hasła etc. Dalej zostaniemy zapytani o to czy chcemy skorzystać z wcześniej przygotowanej GraphQL Schema i jeśli nie, zostanie nam zasugerowane stworzenie takiej schemy. Nasza uproszczona aplikacja będzie miała tylko jeden rodzaj danych — wiadomości, więc wybieramy Single object with fields. Pozostałe typy umożliwiają tworzenie bardziej zaawansowanych relacji między modelami danych. W następnym kroku będziemy mogli zdefiniować naszą schemę. W naszym przypadku obiekt wiadomości powinien mieć 3 pola — identyfikator, autora oraz treść.

Zapisujemy schemę w pliku wskazanym przez Amplify i przechodzimy dalej. Tworzenie konfiguracji naszego API zostało zakończone, teraz przy pomocy polecenia amplify push wygenerujemy nasz backend. Amplify korzysta z CloudFormation, czyli usługi typu infrastrastracture as code (IaC), pozwalającej na tworzenie i zmiany w infrastrukturze przy pomocy kodu. Komenda push publikuje zmiany w tym pliku i aktualizuje stan usług chmurowych używanych przez naszą aplikację. Odpowiadamy na kilka pytań dotyczących naszego API, z których najważniejszy, jest to czy chcemy wygenerować kod wszystkich możliwych mutacji, query i subskrypcji — oczywiście, że chcemy. Następnie tworzone są zasoby, a gdy proces ten zostanie zakończony (zajmie to kilka do kilkunastu minut) nasz backend będzie gotowy.

Gdyśmy zajrzeli teraz do konsoli AWSa moglibyśmy zauważyć, że Amplify stworzył dla nas następujące usługi:

  • AppSync API wraz ze Schema i Resolverami danych,
  • Tabelę DynamoDB,
  • Cognito User Pool i Identity Pool.

Zbudujmy UI

Amplify ułatwi nam także interakcję z backendem, który właśnie stworzyliśmy. W Katalogu ./src znajdziemy teraz plik aws-exports.js, który zawiera opcje konfiguracji wygenerowanego przed chwilą backendu. Aby w pełni skorzystać z mocy tandemu React + Amplify zainstalujmy dwie paczki z NPM – aws-amplify oraz aws-amplify-react. Teraz możemy zaimportować fragmenty Amplify do naszej aplikacji.

Amplify Toolchain stworzył także dla nas katalog graphql, a w nim wszystkie operacje możliwe do wykonania na naszym GraphQL API — mutacje, query i subskrybcje. Zaimportujmy więc definicję tych operacji wraz z wyeksportowanym ustawieniami naszego backendu:

Ostatnią rzeczą, którą musimy zrobić będzie konfiguracja frontendowej biblioteki Amplify — zrobimy to używając metody configure.

W tej chwili biblioteka jest gotowa do użycia. Żeby do naszej aplikacji dodać uwierzytelnianie wystarczy, że użyjemy Higher Order Componentu — opakujmy w niego naszą aplikację.

Gdy uruchomimy naszą aplikację zobaczymy, że ekran powitalny zmieni się teraz w okno logowania. Dodatkowo pojawi się możliwość rejestracji i zmiany hasła. Główny ekran naszej aplikacji będzie teraz dostępny tylko dla użytkowników, którzy się zalogują! Sprawę uwierzytelniania w aplikacji frontendowej mamy załatwioną, pozostaje nam wyświetlić listę wiadomości i zasubskrybować się na nowe. Użyjemy do tego wygenerowanych przez CLI query i subskrybcji.

Pobieranie wiadomości możliwe jest za pomocą query listMessages, a wysłanie tego zapytania do API ułatwi nam funkcja graphql modułu API dostępnego w AWS Amplify. Metoda do pobrania wiadomości może wyglądać np. tak:

Następnie wystarczy, że wywołamy tę metodę w dowolnym momencie cyklu życia komponentu, np. ComponentDidMount. Nie musimy przejmować się uwierzytelnieniem tego zapytania – “pod maską” nasz request zostanie podpisany przez Amplify.

Po pobraniu wiadomości możemy zasubskrybować listę wydarzeń pojawienia się nowych wiadomości bazie danych.

W ten sposób za każdym razem gdy inny użytkownik napisze coś w naszym czacie, wiadomość od razu pojawi się w naszym widoku.

Aby umożliwić naszemu użytkownikowi dodanie wiadomości stworzyć musimy funkcję która umożliwi wykonanie mutacji createMessage.

Następnie pozostaje nam stworzenie wizualnych komponentów — przykład takich komponentów znajdziecie w repozytorium, które stworzyłem przygotowując ten artykuł — github.com/khola/amplify-chat-example/.

Tak przygotowaną aplikację możemy uruchomić i przetestować używając funkcji npm run start. Jeśli wszystko poszło zgodnie z planem i aplikacja działa — pozostaje opublikować ją na serwerze i udostępnić światu — w tym także pomoże nam Amplify. Najpierw dodamy usługę hostingu (amplify add hosting), a później wystarczy użyć komendy amplify publish — nasza aplikacja zostanie zbudowana i opublikowana, a Amplify poda nam adres pod którym nasza aplikacja będzie dostępna.

Podsumowanie

Przy pomocy Amplify możemy tworzyć zasoby w chmurze niemal nie interesując się infrastrukturą — ciężar konfiguracji usług jest zdjęty z barków programisty w maksymalny możliwy sposób. Stworzyliśmy aplikację serverless, która synchronizuje swój stan z serwerem nie pisząc backendowego kodu — jedyne co musieliśmy przygotować to schemat danych trzymanych w bazie! Oczywiście, tworzenie w ten sposób bardziej rozbudowanych produktów będzie trudne, a niniejszy artykuł może przypominać słynny obrazek “how to draw a horse”.

Źródło grafiki

Jeśli jednak musicie stworzyć szybki prototyp, proste narzędzie lub po prostu chcecie spróbować chmury AWS — Amplify sprawdzi się wyśmienicie.

Zapraszamy do dyskusji
Nie ma więcej wpisów

Send this to a friend