sql >> Database teknologi >  >> RDS >> PostgreSQL

Sådan opretter du en serverløs GraphQL API til MySQL, Postgres og Aurora

Oprindeligt opslået på Serverless den 2. juli 2019

Eksponering af en simpel database via en GraphQL API kræver en masse tilpasset kode og infrastruktur:sandt eller falsk?

For dem, der svarede "sandt", er vi her for at vise dig, at det faktisk er ret nemt at bygge GraphQL API'er, med nogle konkrete eksempler til at illustrere hvorfor og hvordan.

(Hvis du allerede ved, hvor nemt det er at bygge GraphQL API'er med serverløs, er der også masser for dig i denne artikel.)

GraphQL er et forespørgselssprog til web-API'er. Der er en vigtig forskel mellem en konventionel REST API og API'er baseret på GraphQL:med GraphQL kan du bruge en enkelt anmodning til at hente flere entiteter på én gang. Dette resulterer i hurtigere sideindlæsninger og muliggør en enklere struktur for dine frontend-apps, hvilket resulterer i en bedre weboplevelse for alle. Hvis du aldrig har brugt GraphQL før, foreslår vi, at du tjekker denne GraphQL-tutorial for en hurtig introduktion.

Serverless frameworket passer godt til GraphQL API'er:med Serverless behøver du ikke bekymre dig om at køre, administrere og skalere dine egne API-servere i skyen, og du behøver ikke at skrive nogen infrastrukturautomatiseringsscripts. Lær mere om Serverless her. Derudover giver Serverless en fremragende leverandør-agnostisk udvikleroplevelse og et robust fællesskab til at hjælpe dig med at bygge dine GraphQL-applikationer.

Mange applikationer i vores daglige erfaring indeholder sociale netværksfunktioner, og den slags funktionalitet kan virkelig drage fordel af at implementere GraphQL i stedet for REST-modellen, hvor det er svært at afsløre strukturer med indlejrede entiteter, som brugere og deres Twitter-opslag. Med GraphQL kan du bygge et samlet API-slutpunkt, der giver dig mulighed for at forespørge, skrive og redigere alle de entiteter, du har brug for, ved hjælp af en enkelt API-anmodning.

I denne artikel ser vi på, hvordan man opbygger en simpel GraphQL API ved hjælp af den serverløse ramme, Node.js, og en hvilken som helst af flere hostede databaseløsninger, der er tilgængelige via Amazon RDS:MySQL, PostgreSQL og MySQL workalike Amazon Aurora.

Følg med i dette eksempellager på GitHub, og lad os dykke ind!

Opbygning af et GraphQL API med en relationel DB-backend

I vores eksempelprojekt besluttede vi at bruge alle tre databaser (MySQL, PostgreSQL og Aurora) i den samme kodebase. Vi ved, det er overkill selv for en produktionsapp, men vi ville blæse dig væk med, hvordan web-skala vi bygger. 😉

Men seriøst, vi overfyldte projektet bare for at sikre, at du ville finde et relevant eksempel, der gælder for din yndlingsdatabase. Hvis du gerne vil se eksempler med andre databaser, så lad os det vide i kommentarerne.

Definition af GraphQL-skemaet

Lad os starte med at definere skemaet for GraphQL API'en, som vi vil oprette, hvilket vi gør i filen schema.gql i roden af ​​vores projekt ved hjælp af GraphQL-syntaksen. Hvis du ikke er bekendt med denne syntaks, så tag et kig på eksemplerne på denne GraphQL-dokumentationsside.

Til at begynde med tilføjer vi de første to elementer til skemaet:en brugerentitet og en post-entitet, og definerer dem som følger, så hver bruger kan have flere post-enheder tilknyttet:

skriv Bruger {

UUID:Streng

Navn:Streng

Indlæg:[Indlæg]

}

skriv Post {

UUID:Streng

Tekst:Streng

}

Vi kan nu se, hvordan bruger- og post-enhederne ser ud. Senere sørger vi for, at disse felter kan gemmes direkte i vores databaser.

Lad os derefter definere, hvordan brugere af API'en vil forespørge på disse enheder. Selvom vi kunne bruge de to GraphQL-typer Bruger og Post direkte i vores GraphQL-forespørgsler, er det bedste praksis at oprette inputtyper i stedet for at holde skemaet enkelt. Så vi går videre og tilføjer to af disse inputtyper, en til indlæggene og en til brugerne:

input UserInput {

Navn:Streng

Indlæg:[PostInput]

}

input PostInput {

Tekst:Streng

}

Lad os nu definere mutationerne - de operationer, der ændrer de data, der er gemt i vores databaser via vores GraphQL API. Til dette opretter vi en mutationstype. Den eneste mutation, vi vil bruge indtil videre, er createUser. Da vi bruger tre forskellige databaser, tilføjer vi en mutation for hver databasetype. Hver af mutationerne accepterer input UserInput og returnerer en brugerentitet:


Vi ønsker også at tilbyde en måde at forespørge brugerne på, så vi opretter en forespørgselstype med én forespørgsel pr. databasetype. Hver forespørgsel accepterer en streng, der er brugerens UUID, og ​​returnerer den brugerentitet, der indeholder dens navn, UUID og en samling af alle tilknyttede Pos``t:

Til sidst definerer vi skemaet og peger på forespørgsels- og mutationstyperne:
schema { query: Query mutation: Mutation }

Vi har nu en komplet beskrivelse af vores nye GraphQL API! Du kan se hele filen her.

Definition af behandlere til GraphQL API

Nu hvor vi har en beskrivelse af vores GraphQL API, kan vi skrive den kode, vi har brug for til hver forespørgsel og mutation. Vi starter med at oprette en handler.js-fil i roden af ​​projektet, lige ved siden af ​​schema.gql-filen, vi oprettede tidligere.

handler.js' første opgave er at læse skemaet:



TypeDefs-konstanten indeholder nu definitionerne for vores GraphQL-entiteter. Dernæst specificerer vi, hvor koden til vores funktioner skal bo. For at holde tingene klare opretter vi en separat fil for hver forespørgsel og mutation:



Resolver-konstanten indeholder nu definitionerne for alle vores API's funktioner. Vores næste skridt er at oprette GraphQL-serveren. Kan du huske graphql-yoga-biblioteket, vi krævede ovenfor? Vi bruger det bibliotek her til at skabe en fungerende GraphQL-server nemt og hurtigt:



Til sidst eksporterer vi GraphQL-handleren sammen med GraphQL Playground-handleren (som giver os mulighed for at prøve vores GraphQL API i en webbrowser):



Okay, vi er færdige med filen handler.js for nu. Næste op:skrive kode til alle funktioner, der tilgår databaserne.

Skriv kode for forespørgslerne og mutationerne

Vi har nu brug for kode for at få adgang til databaserne og for at drive vores GraphQL API. I roden af ​​vores projekt opretter vi følgende struktur for vores MySQL-resolverfunktioner, med de andre databaser, der skal følges:


Almindelige forespørgsler

I Common-mappen udfylder vi mysql.js-filen med det, vi skal bruge til createUser-mutationen og getUser-forespørgslen:en init-forespørgsel, for at oprette tabeller til brugere og indlæg, hvis de ikke eksisterer endnu; og en brugerforespørgsel, for at returnere en brugers data, når der oprettes og forespørges for en bruger. Vi bruger dette i både mutationen og forespørgslen.

Init-forespørgslen opretter både bruger- og indlægstabellerne som følger:


GetUser-forespørgslen returnerer brugeren og deres indlæg:

Begge disse funktioner eksporteres; vi kan derefter få adgang til dem i filen handler.js.

Skrivning af mutationen

Tid til at skrive koden til createUser-mutationen, som skal acceptere navnet på den nye bruger, samt en liste over alle indlæg, der tilhører dem. For at gøre dette opretter vi filen resolver/Mutation/mysql_createUser.js med en enkelt eksporteret func-funktion for mutationen:


Mutationsfunktionen skal gøre følgende ting i rækkefølge:
  1. Opret forbindelse til databasen ved hjælp af legitimationsoplysningerne i applikationens miljøvariabler.

  2. Indsæt brugeren i databasen ved hjælp af brugernavnet, der er angivet som input til mutationen.

  3. Indsæt også eventuelle indlæg, der er knyttet til brugeren, givet som input til mutationen.

  4. Returner de oprettede brugerdata.

Sådan opnår vi det i kode:


Du kan se den fulde fil, der definerer mutationen her.

Skrivning af forespørgslen

getUser-forespørgslen har en struktur, der ligner den mutation, vi lige har skrevet, men denne er endnu enklere. Nu hvor getUser-funktionen er i Common namespace, har vi ikke længere brug for nogen tilpasset SQL i forespørgslen. Så vi opretter filen resolver/Query/mysql_getUser.js som følger:


Du kan se hele forespørgslen i denne fil.

Samling af alt i filen serverless.yml

Lad os tage et skridt tilbage. Vi har i øjeblikket følgende:

  • Et GraphQL API-skema.

  • En handler.js-fil.

  • En fil til almindelige databaseforespørgsler.

  • En fil for hver mutation og forespørgsel.

Det sidste trin er at forbinde alt dette via filen serverless.yml. Vi opretter en tom serverless.yml i roden af ​​projektet og starter med at definere udbyderen, regionen og runtime. Vi anvender også LambdaRole IAM-rollen (som vi definerer senere her) på vores projekt:


Vi definerer derefter miljøvariablerne for databaselegitimationsoplysningerne:

Bemærk, at alle variabler refererer til den tilpassede sektion, som kommer dernæst og indeholder de faktiske værdier for variablerne. Bemærk, at adgangskoden er en forfærdelig adgangskode til din database og bør ændres til noget mere sikkert (måske p@ssw0rd 😃):

Hvad er de referencer efter Fn::GettAtt, spørger du? De henviser til databaseressourcer:

Resource/MySqlRDSInstance.yml-filen definerer alle MySQL-forekomstens attributter. Du kan finde det fulde indhold her.

Til sidst definerer vi i filen serverless.yml to funktioner, graphql og playground. graphql-funktionen kommer til at håndtere alle API-anmodninger, og playground-slutpunktet vil skabe en forekomst af GraphQL Playground for os, hvilket er en fantastisk måde at prøve vores GraphQL API i en webbrowser:


Nu er MySQL-support til vores applikation komplet!

Du kan finde det fulde indhold af filen serverless.yml her.

Tilføjelse af Aurora- og PostgreSQL-understøttelse

Vi har allerede skabt al den struktur, vi har brug for til at understøtte andre databaser i dette projekt. For at tilføje support til Aurora og Postgres behøver vi kun at definere koden for deres mutationer og forespørgsler, hvilket vi gør som følger:

  1. Tilføj en almindelig forespørgselsfil for Aurora og for Postgres.

  2. Tilføj createUser-mutationen for begge databaser.

  3. Tilføj getUser-forespørgslen for begge databaser.

  4. Tilføj konfiguration i filen serverless.yml for alle miljøvariabler og ressourcer, der er nødvendige for begge databaser.

På dette tidspunkt har vi alt, hvad vi behøver for at implementere vores GraphQL API, drevet af MySQL, Aurora og PostgreSQL.

Implementering og test af GraphQL API

Implementeringen af ​​vores GraphQL API er enkel.

  • Først kører vi npm install for at sætte vores afhængigheder på plads.

  • Derefter kører vi npm run deploy, som opsætter alle vores miljøvariabler og udfører implementeringen.

  • Under motorhjelmen kører denne kommando serverløs implementering ved hjælp af det rigtige miljø.

Det er det! I outputtet af implementeringstrinnet ser vi URL-slutpunktet for vores implementerede applikation. Vi kan udstede POST-anmodninger til vores GraphQL API ved hjælp af denne URL, og vores Playground (som vi leger med om et sekund) er tilgængelig ved at bruge GET mod den samme URL.

Prøver API'en i GraphQL Playground

GraphQL Playground, som er det, du ser, når du besøger den pågældende URL i browseren, er en fantastisk måde at prøve vores API.

Lad os oprette en bruger ved at køre følgende mutation:

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 } }

I denne mutation kalder vi mysql_createUser API, leverer teksten til den nye brugers indlæg og angiver, at vi ønsker at få brugerens navn og UUID tilbage som svar.

Indsæt ovenstående tekst i venstre side af legepladsen, og klik på knappen Afspil. Til højre kan du se outputtet af forespørgslen:



Lad os nu forespørge efter denne bruger:

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

Dette giver os navnet og UUID'et for den bruger, vi lige har oprettet, tilbage. Pænt!



Vi kan gøre det samme med de andre backends, PostgreSQL og Aurora. Til det skal vi blot erstatte navnene på mutationen med postgres_createUser eller aurora_createUser, og forespørgsler med postgres_getUser eller aurora_getUser. Prøv det selv! (Husk, at brugerne ikke synkroniseres mellem databaserne, så du vil kun være i stand til at forespørge efter brugere, som du har oprettet i hver specifik database.)

Sammenligning af MySQL-, PostgreSQL- og Aurora-implementeringerne

Til at begynde med ser mutationer og forespørgsler nøjagtigt ens ud på Aurora og MySQL, da Aurora er MySQL-kompatibel. Og der er kun minimale kodeforskelle mellem disse to og Postgres-implementeringen.

Faktisk er den største forskel mellem vores tre databaser, for simple use cases, at Aurora kun er tilgængelig som en klynge. Den mindste tilgængelige Aurora-konfiguration inkluderer stadig en skrivebeskyttet og en skrive-replika, så vi har brug for en klyngekonfiguration selv for denne grundlæggende Aurora-implementering.

Aurora tilbyder hurtigere ydeevne end MySQL og PostgreSQL, hovedsageligt på grund af SSD-optimeringerne, som Amazon har lavet til databasemotoren. Efterhånden som dit projekt vokser, vil du sandsynligvis opdage, at Aurora tilbyder forbedret databaseskalerbarhed, lettere vedligeholdelse og bedre pålidelighed sammenlignet med standard MySQL- og PostgreSQL-konfigurationer. Men du kan også lave nogle af disse forbedringer på MySQL og PostgreSQL, hvis du justerer dine databaser og tilføjer replikering.

Til testprojekter og legepladser anbefaler vi MySQL eller PostgreSQL. Disse kan køre på db.t2.micro RDS-forekomster, som er en del af AWS free tier. Aurora tilbyder i øjeblikket ikke db.t2.micro-forekomster, så du vil betale lidt mere for at bruge Aurora til dette testprojekt.

En sidste vigtig bemærkning

Husk at fjerne din serverløse implementering når du er færdig med at prøve GraphQL API, så du ikke bliver ved med at betale for databaseressourcer, du ikke længere bruger.

Du kan fjerne stakken oprettet i dette eksempel ved at køre npm run remove i roden af ​​projektet.

God fornøjelse med at eksperimentere!

Resumé

I denne artikel ledte vi dig gennem oprettelse af en simpel GraphQL API, ved at bruge tre forskellige databaser på én gang; Selvom dette ikke er noget, du nogensinde ville gøre i virkeligheden, gav det os mulighed for at sammenligne simple implementeringer af Aurora-, MySQL- og PostgreSQL-databaserne. Vi så, at implementeringen for alle tre databaser er nogenlunde den samme i vores simple tilfælde, bortset fra mindre forskelle i syntaksen og implementeringskonfigurationerne.

Du kan finde det fulde eksempelprojekt, som vi har brugt i denne GitHub-repo. Den nemmeste måde at eksperimentere med projektet på er at klone repo'en og implementere den fra din maskine ved hjælp af npm run deploy.

For flere GraphQL API-eksempler, der bruger Serverless, tjek serverless-graphql-repoen.

Hvis du gerne vil lære mere om at køre Serverless GraphQL API'er i stor skala, kan du måske nyde vores artikelserie "Køre et skalerbart og pålideligt GraphQL-endepunkt med Serverless"

Måske er GraphQL bare ikke din jam, og du vil hellere implementere en REST API? Vi har dig dækket:Tjek dette blogindlæg for nogle eksempler.

Spørgsmål? Kommenter dette indlæg, eller opret en diskussion i vores forum.

Oprindeligt udgivet på https://www.serverless.com.


  1. mærkelig tegnkodning af lagrede data, gammelt script viser dem fint, nyt gør det ikke

  2. MySQL pivottabelforespørgsel med dynamiske kolonner

  3. JSON_ARRAY_INSERT() – Indsæt værdier i et JSON-array i MySQL

  4. 5 almindelige fejl at undgå, når du de-duperer dine data