PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak stworzyć bezserwerowe API GraphQL dla MySQL, Postgres i Aurora?

Pierwotnie opublikowano w Serverless 2 lipca 2019 r.

Ujawnienie prostej bazy danych za pośrednictwem interfejsu API GraphQL wymaga dużo niestandardowego kodu i infrastruktury:prawda czy fałsz?

Dla tych, którzy odpowiedzieli „prawda”, jesteśmy tutaj, aby pokazać, że budowanie interfejsów API GraphQL jest w rzeczywistości dość łatwe, z kilkoma konkretnymi przykładami ilustrującymi, dlaczego i jak.

(Jeśli już wiesz, jak łatwe jest budowanie interfejsów API GraphQL w trybie bezserwerowym, w tym artykule jest również wiele dla Ciebie.)

GraphQL to język zapytań dla internetowych interfejsów API. Istnieje kluczowa różnica między konwencjonalnym interfejsem API REST a interfejsami API opartymi na GraphQL:dzięki GraphQL możesz użyć jednego żądania do pobrania wielu jednostek jednocześnie. Skutkuje to szybszym ładowaniem stron i prostszą strukturą aplikacji frontendowych, co zapewnia lepsze środowisko internetowe dla wszystkich. Jeśli nigdy wcześniej nie korzystałeś z GraphQL, zalecamy zapoznanie się z tym samouczkiem GraphQL, aby uzyskać krótkie wprowadzenie.

Framework bezserwerowy doskonale pasuje do interfejsów API GraphQL:dzięki bezserwerowemu nie musisz się martwić o uruchamianie, zarządzanie i skalowanie własnych serwerów API w chmurze i nie musisz pisać żadnych skryptów automatyzacji infrastruktury. Dowiedz się więcej o bezserwerowym tutaj. Ponadto Serverless zapewnia doskonałe, niezależne od dostawcy środowisko programistów i solidną społeczność, która pomoże Ci w tworzeniu aplikacji GraphQL.

Wiele aplikacji w naszym codziennym doświadczeniu zawiera funkcje sieci społecznościowych, a tego rodzaju funkcjonalność może naprawdę skorzystać na zaimplementowaniu GraphQL zamiast modelu REST, w którym trudno jest ujawnić struktury z zagnieżdżonymi jednostkami, takimi jak użytkownicy i ich posty na Twitterze. Dzięki GraphQL możesz zbudować ujednolicony punkt końcowy API, który pozwala na wysyłanie zapytań, pisanie i edycję wszystkich potrzebnych encji za pomocą pojedynczego żądania API.

W tym artykule przyjrzymy się, jak zbudować prosty interfejs API GraphQL za pomocą frameworka bezserwerowego, Node.js i dowolnego z kilku hostowanych rozwiązań baz danych dostępnych za pośrednictwem Amazon RDS:MySQL, PostgreSQL i działającego podobnie do MySQL Amazon Aurora.

Postępuj zgodnie z tym przykładowym repozytorium na GitHub i zanurkujmy!

Budowanie API GraphQL z relacyjnym zapleczem bazy danych

W naszym przykładowym projekcie zdecydowaliśmy się na użycie wszystkich trzech baz danych (MySQL, PostgreSQL i Aurora) w tej samej bazie kodu. Wiemy, że to przesada, nawet jak na aplikację produkcyjną, ale chcieliśmy cię zaskoczyć tym, jak tworzymy skalę internetową.

Ale poważnie, przepełniliśmy projekt, aby upewnić się, że znajdziesz odpowiedni przykład, który pasuje do Twojej ulubionej bazy danych. Jeśli chcesz zobaczyć przykłady z innymi bazami danych, daj nam znać w komentarzach.

Definiowanie schematu GraphQL

Zacznijmy od zdefiniowania schematu GraphQL API, który chcemy stworzyć, co robimy w pliku schema.gql w katalogu głównym naszego projektu przy użyciu składni GraphQL. Jeśli nie znasz tej składni, spójrz na przykłady na tej stronie dokumentacji GraphQL.

Na początek dodajemy pierwsze dwa elementy do schematu:encję użytkownika i encję Post, definiując je w następujący sposób, tak aby każdy użytkownik mógł mieć wiele powiązanych encji Post:

wpisz Użytkownik {

UUID:ciąg

Nazwa:Ciąg

Posty:[Post]

}

wpisz post {

UUID:ciąg

Tekst:ciąg

}

Możemy teraz zobaczyć, jak wyglądają encje User i Post. Później upewnimy się, że te pola mogą być przechowywane bezpośrednio w naszych bazach danych.

Następnie zdefiniujmy, w jaki sposób użytkownicy interfejsu API będą wysyłać zapytania do tych encji. Chociaż moglibyśmy użyć dwóch typów GraphQL User i Post bezpośrednio w naszych zapytaniach GraphQL, najlepszą praktyką jest tworzenie typów wejściowych zamiast tego, aby schemat był prosty. Więc idziemy dalej i dodajemy dwa z tych typów danych wejściowych, jeden dla postów i jeden dla użytkowników:

wprowadź UserInput {

Nazwa:Ciąg

Posty:[PostInput]

}

wejście PostInput {

Tekst:ciąg

}

Teraz zdefiniujmy mutacje – operacje, które modyfikują dane przechowywane w naszych bazach danych za pośrednictwem naszego GraphQL API. W tym celu tworzymy typ mutacji. Jedyną mutacją, której na razie użyjemy, jest createUser. Ponieważ używamy trzech różnych baz danych, dodajemy mutację dla każdego typu bazy danych. Każda z mutacji akceptuje dane wejściowe UserInput i zwraca encję User:


Chcemy również zapewnić sposób wysyłania zapytań do użytkowników, dlatego tworzymy typ zapytania z jednym zapytaniem na typ bazy danych. Każde zapytanie akceptuje String, który jest UUID użytkownika, zwracając encję User, która zawiera jego nazwę, UUID i kolekcję wszystkich powiązanych pozycji:

Na koniec definiujemy schemat i wskazujemy typy Query i Mutation:
schema { query: Query mutation: Mutation }

Mamy teraz pełny opis naszego nowego API GraphQL! Tutaj możesz zobaczyć cały plik.

Definiowanie modułów obsługi dla GraphQL API

Teraz, gdy mamy już opis naszego API GraphQL, możemy napisać kod, którego potrzebujemy dla każdego zapytania i mutacji. Zaczynamy od utworzenia pliku handler.js w katalogu głównym projektu, tuż obok utworzonego wcześniej pliku schema.gql.

Pierwszym zadaniem handler.js jest odczytanie schematu:



Stała typeDefs zawiera teraz definicje naszych encji GraphQL. Następnie określamy, gdzie ma znajdować się kod naszych funkcji. Aby wszystko było jasne, utworzymy osobny plik dla każdego zapytania i mutacji:



Stała rozpoznawania nazw zawiera teraz definicje wszystkich funkcji naszego API. Naszym kolejnym krokiem jest stworzenie serwera GraphQL. Pamiętasz bibliotekę graphql-yoga, której potrzebowaliśmy powyżej? Wykorzystamy tę bibliotekę tutaj, aby łatwo i szybko stworzyć działający serwer GraphQL:



Na koniec eksportujemy procedurę obsługi GraphQL wraz z obsługą GraphQL Playground (co pozwoli nam wypróbować nasze API GraphQL w przeglądarce internetowej):



Ok, na razie skończyliśmy z plikiem handler.js. Dalej:pisanie kodu dla wszystkich funkcji, które uzyskują dostęp do baz danych.

Pisanie kodu dla zapytań i mutacji

Teraz potrzebujemy kodu, aby uzyskać dostęp do baz danych i zasilić nasze API GraphQL. W katalogu głównym naszego projektu tworzymy następującą strukturę dla naszych funkcji przelicznika MySQL, z innymi bazami danych do naśladowania:


Typowe zapytania

W folderze Common wypełniamy plik mysql.js tym, czego potrzebujemy do mutacji createUser i zapytania getUser:zapytaniem init, aby utworzyć tabele dla użytkowników i postów, jeśli jeszcze nie istnieją; oraz zapytanie użytkownika, aby zwrócić dane użytkownika podczas tworzenia i wysyłania zapytań dla użytkownika. Użyjemy tego zarówno w mutacji, jak i zapytaniu.

Zapytanie init tworzy zarówno tabele Users, jak i Posts w następujący sposób:


Zapytanie getUser zwraca użytkownika i jego posty:

Obie te funkcje są eksportowane; możemy wtedy uzyskać do nich dostęp w pliku handler.js.

Zapisywanie mutacji

Czas napisać kod dla mutacji createUser, która musi zaakceptować nazwę nowego użytkownika, a także listę wszystkich wpisów, które do niego należą. W tym celu tworzymy plik resolver/Mutation/mysql_createUser.js z pojedynczą wyeksportowaną funkcją func dla mutacji:


Funkcja mutacji musi wykonać następujące czynności, w kolejności:
  1. Połącz się z bazą danych, używając danych logowania w zmiennych środowiskowych aplikacji.

  2. Wstaw użytkownika do bazy danych, używając nazwy użytkownika podanej jako dane wejściowe do mutacji.

  3. Wstaw także wszelkie posty powiązane z użytkownikiem, dostarczone jako dane wejściowe do mutacji.

  4. Zwróć utworzone dane użytkownika.

Oto jak osiągamy to w kodzie:


Tutaj możesz zobaczyć pełny plik, który definiuje mutację.

Pisanie zapytania

Zapytanie getUser ma strukturę podobną do mutacji, którą właśnie napisaliśmy, ale ta jest jeszcze prostsza. Teraz, gdy funkcja getUser znajduje się we wspólnej przestrzeni nazw, nie potrzebujemy już w zapytaniu żadnego niestandardowego kodu SQL. Tak więc tworzymy plik resolver/Query/mysql_getUser.js w następujący sposób:


Możesz zobaczyć pełne zapytanie w tym pliku.

Łączenie wszystkiego w pliku serverless.yml

Cofnijmy się o krok. Obecnie mamy następujące:

  • Schemat API GraphQL.

  • Plik handler.js.

  • Plik do typowych zapytań do bazy danych.

  • Plik dla każdej mutacji i zapytania.

Ostatnim krokiem jest połączenie tego wszystkiego razem za pomocą pliku serverless.yml. Tworzymy pusty plik serverless.yml w katalogu głównym projektu i zaczynamy od zdefiniowania dostawcy, regionu i środowiska wykonawczego. Do naszego projektu stosujemy również rolę LambdaRole IAM (którą tutaj definiujemy później):


Następnie definiujemy zmienne środowiskowe dla poświadczeń bazy danych:

Zwróć uwagę, że wszystkie zmienne odwołują się do sekcji niestandardowej, która jest następna i zawiera rzeczywiste wartości zmiennych. Pamiętaj, że hasło jest okropnym hasłem do twojej bazy danych i powinno zostać zmienione na coś bardziej bezpiecznego (być może p@ssw0rd 😃):

Pytasz, jakie są te odniesienia po Fn::GettAtt? Odnoszą się one do zasobów bazy danych:

Plik resource/MySqlRDSInstance.yml definiuje wszystkie atrybuty instancji MySQL. Jego pełną treść znajdziesz tutaj.

Na koniec w pliku serverless.yml definiujemy dwie funkcje, graphql i plac zabaw. Funkcja graphql obsłuży wszystkie żądania API, a punkt końcowy placu zabaw utworzy dla nas instancję GraphQL Playground, co jest świetnym sposobem na wypróbowanie naszego GraphQL API w przeglądarce internetowej:


Teraz obsługa MySQL dla naszej aplikacji jest zakończona!

Pełną zawartość pliku serverless.yml znajdziesz tutaj.

Dodawanie obsługi Aurory i PostgreSQL

Stworzyliśmy już całą strukturę potrzebną do obsługi innych baz danych w tym projekcie. Aby dodać obsługę Aurory i Postgresa, wystarczy zdefiniować kod ich mutacji i zapytań, co robimy w następujący sposób:

  1. Dodaj plik wspólnych zapytań dla Aurory i Postgresa.

  2. Dodaj mutację createUser dla obu baz danych.

  3. Dodaj zapytanie getUser dla obu baz danych.

  4. Dodaj konfigurację w pliku serverless.yml dla wszystkich zmiennych środowiskowych i zasobów potrzebnych dla obu baz danych.

W tym momencie mamy wszystko, czego potrzebujemy do wdrożenia naszego GraphQL API, obsługiwanego przez MySQL, Aurora i PostgreSQL.

Wdrażanie i testowanie GraphQL API

Wdrożenie naszego GraphQL API jest proste.

  • Najpierw uruchamiamy instalację npm, aby umieścić nasze zależności.

  • Następnie uruchamiamy npm run deploy, które konfiguruje wszystkie nasze zmienne środowiskowe i wykonuje wdrożenie.

  • Pod maską to polecenie uruchamia wdrażanie bezserwerowe w odpowiednim środowisku.

Otóż ​​to! W danych wyjściowych kroku wdrażania zobaczymy punkt końcowy adresu URL dla naszej wdrożonej aplikacji. Możemy wysyłać żądania POST do naszego GraphQL API za pomocą tego adresu URL, a nasz plac zabaw (z którym będziemy się bawić za sekundę) jest dostępny za pomocą GET dla tego samego adresu URL.

Wypróbowanie interfejsu API w GraphQL Playground

GraphQL Playground, czyli to, co widzisz podczas odwiedzania tego adresu URL w przeglądarce, to świetny sposób na wypróbowanie naszego API.

Utwórzmy użytkownika, uruchamiając następującą mutację:

mutation { mysql_createUser( input: { Name: "Cicero" Posts: [ { Text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit." } { Text: "Proin consequat mauris orci, ut consequat purus efficitur vel." } ] } ) { Name UUID } }

W tej mutacji wywołujemy mysql_createUser API, dostarczamy tekst postów nowego użytkownika i wskazujemy, że chcemy odzyskać nazwę użytkownika i UUID jako odpowiedź.

Wklej powyższy tekst po lewej stronie Placu zabaw i kliknij przycisk Odtwórz. Po prawej stronie zobaczysz wynik zapytania:



Teraz zapytajmy o tego użytkownika:

query { mysql_getUser(uuid: "f5593682-6bf1-466a-967d-98c7e9da844b") { Name UUID } }

Zwraca nam to nazwę i UUID użytkownika, którego właśnie utworzyliśmy. Schludny!



Możemy zrobić to samo z innymi backendami, PostgreSQL i Aurora. W tym celu wystarczy zastąpić nazwy mutacji postgres_createUser lub aurora_createUser, a zapytania postgres_getUser lub aurora_getUser. Wypróbuj sam! (Pamiętaj, że użytkownicy nie są synchronizowani między bazami danych, więc będziesz mógł wysyłać zapytania tylko o użytkowników, których utworzyłeś w każdej określonej bazie danych).

Porównanie implementacji MySQL, PostgreSQL i Aurora

Po pierwsze, mutacje i zapytania wyglądają dokładnie tak samo w Aurorze i MySQL, ponieważ Aurora jest kompatybilna z MySQL. I są tylko minimalne różnice w kodzie między tymi dwoma a implementacją Postgres.

W rzeczywistości, w prostych przypadkach największą różnicą między naszymi trzema bazami danych jest to, że Aurora jest dostępna tylko jako klaster. Najmniejsza dostępna konfiguracja Aurora nadal zawiera jedną replikę tylko do odczytu i jedną do zapisu, więc potrzebujemy konfiguracji klastrowej nawet w przypadku tego podstawowego wdrożenia Aurora.

Aurora oferuje wyższą wydajność niż MySQL i PostgreSQL, głównie ze względu na optymalizację SSD dokonaną przez Amazon w silniku bazy danych. W miarę rozwoju projektu prawdopodobnie przekonasz się, że Aurora oferuje lepszą skalowalność bazy danych, łatwiejszą konserwację i lepszą niezawodność w porównaniu z domyślnymi konfiguracjami MySQL i PostgreSQL. Ale możesz wprowadzić niektóre z tych ulepszeń w MySQL i PostgreSQL, jeśli dostroisz swoje bazy danych i dodasz replikację.

Do projektów testowych i placów zabaw polecamy MySQL lub PostgreSQL. Mogą one działać na instancjach db.t2.micro RDS, które są częścią bezpłatnej warstwy AWS. Aurora nie oferuje obecnie instancji db.t2.micro, więc zapłacisz trochę więcej za korzystanie z Aurory w tym projekcie testowym.

Ostatnia ważna uwaga

Pamiętaj, aby usunąć wdrożenie bezserwerowe po zakończeniu testowania GraphQL API, aby nie płacić za zasoby bazy danych, których już nie używasz.

Możesz usunąć stos utworzony w tym przykładzie, uruchamiając npm run remove w katalogu głównym projektu.

Miłego eksperymentowania!

Podsumowanie

W tym artykule przeprowadziliśmy Cię przez proces tworzenia prostego API GraphQL, wykorzystującego jednocześnie trzy różne bazy danych; chociaż w rzeczywistości nie jest to coś, co zrobisz, pozwoliło nam to porównać proste implementacje baz danych Aurora, MySQL i PostgreSQL. Widzieliśmy, że implementacja dla wszystkich trzech baz danych jest mniej więcej taka sama w naszym prostym przypadku, z wyjątkiem niewielkich różnic w składni i konfiguracjach wdrażania.

Możesz znaleźć pełny przykładowy projekt, którego używaliśmy w tym repozytorium GitHub. Najłatwiejszym sposobem na eksperymentowanie z projektem jest sklonowanie repozytorium i wdrożenie go ze swojej maszyny za pomocą npm run deploy.

Aby uzyskać więcej przykładów API GraphQL korzystającego z bezserwerowego, sprawdź repozytorium serverless-graphql.

Jeśli chcesz dowiedzieć się więcej o uruchamianiu bezserwerowych interfejsów API GraphQL na dużą skalę, możesz zapoznać się z naszą serią artykułów „Uruchamianie skalowalnego i niezawodnego punktu końcowego GraphQL bez użycia serwera”

Może GraphQL po prostu nie jest twoją przeszkodą i wolisz wdrożyć API REST? Zapewniamy Cię:sprawdź ten post na blogu, aby zapoznać się z kilkoma przykładami.

Pytania? Skomentuj ten post lub utwórz dyskusję na naszym forum.

Pierwotnie opublikowany na https://www.serverless.com.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak skonfigurować HikariCP dla postgresql?

  2. Zadanie cron do usuwania starych danych z postgres na debianie

  3. Jak Mod() działa w PostgreSQL

  4. Docelowy czas przywracania Pgbackrest

  5. Uruchamianie PostgreSQL przy użyciu Amazon RDS