Původně zveřejněno na Serverless 2. července 2019
Zpřístupnění jednoduché databáze prostřednictvím GraphQL API vyžaduje spoustu vlastního kódu a infrastruktury:pravda nebo ne?
Pro ty, kteří odpověděli „pravda“, jsme tu, abychom vám ukázali, že vytváření rozhraní GraphQL API je ve skutečnosti poměrně snadné, s několika konkrétními příklady, které ilustrují proč a jak.
(Pokud již víte, jak snadné je vytvářet GraphQL API pomocí Serverless, v tomto článku je toho pro vás také dost.)
GraphQL je dotazovací jazyk pro webová rozhraní API. Mezi konvenčním REST API a API založenými na GraphQL je klíčový rozdíl:s GraphQL můžete použít jeden požadavek k načtení více entit najednou. To vede k rychlejšímu načítání stránek a umožňuje jednodušší strukturu pro vaše frontendové aplikace, což má za následek lepší webový zážitek pro všechny. Pokud jste nikdy předtím GraphQL nepoužívali, doporučujeme vám, abyste si prohlédli tento tutoriál GraphQL, kde najdete rychlý úvod.
Serverless framework se skvěle hodí pro GraphQL API:s Serverless se nemusíte starat o provoz, správu a škálování vlastních API serverů v cloudu a nebudete muset psát žádné skripty pro automatizaci infrastruktury. Více o Serverless se dozvíte zde. Serverless navíc poskytuje vynikající vývojářské prostředí bez ohledu na dodavatele a robustní komunitu, která vám pomůže při vytváření aplikací GraphQL.
Mnoho aplikací v naší každodenní zkušenosti obsahuje funkce sociálních sítí a tento druh funkcí může skutečně těžit z implementace GraphQL namísto modelu REST, kde je obtížné odhalit struktury s vnořenými entitami, jako jsou uživatelé a jejich příspěvky na Twitteru. S GraphQL můžete vytvořit jednotný koncový bod API, který vám umožní dotazovat se, zapisovat a upravovat všechny entity, které potřebujete, pomocí jediného požadavku API.
V tomto článku se podíváme na to, jak vytvořit jednoduché rozhraní GraphQL API s pomocí bezserverového rámce, Node.js a libovolného z několika hostovaných databázových řešení dostupných prostřednictvím Amazon RDS:MySQL, PostgreSQL a MySQL workalike Amazon Aurora.
Postupujte podle tohoto příkladu úložiště na GitHubu a pojďme se ponořit!
Vytvoření GraphQL API s relačním DB backendem
V našem vzorovém projektu jsme se rozhodli použít všechny tři databáze (MySQL, PostgreSQL a Aurora) ve stejné kódové základně. Víme, že je to přehnané i pro produkční aplikaci, ale chtěli jsme vás strhnout tím, jak webovou stránku vytváříme. 😉
Ale vážně, projekt jsme přecpali jen proto, abychom se ujistili, že najdete relevantní příklad, který platí pro vaši oblíbenou databázi. Pokud byste chtěli vidět příklady s jinými databázemi, dejte nám prosím vědět v komentářích.
Definování schématu GraphQL
Začněme definováním schématu rozhraní GraphQL API, které chceme vytvořit, což provedeme v souboru schema.gql v kořenovém adresáři našeho projektu pomocí syntaxe GraphQL. Pokud tuto syntaxi neznáte, podívejte se na příklady na této stránce dokumentace GraphQL.
Pro začátek přidáváme do schématu první dvě položky:entitu User a entitu Post, přičemž je definujeme následovně, aby každý uživatel mohl mít přidruženo více entit Post:
zadejte Uživatel {
UUID:Řetězec
Název:Řetězec
Příspěvky:[Příspěvek]
}
zadejte příspěvek {
UUID:Řetězec
Text:Řetězec
}
Nyní můžeme vidět, jak vypadají entity User a Post. Později se ujistíme, že tato pole mohou být uložena přímo v našich databázích.
Dále definujeme, jak budou uživatelé rozhraní API tyto entity dotazovat. I když bychom mohli použít dva typy GraphQL User a Post přímo v našich dotazech GraphQL, je nejlepším postupem místo toho vytvořit vstupní typy, aby bylo schéma jednoduché. Pokračujeme a přidáme dva z těchto typů vstupu, jeden pro příspěvky a jeden pro uživatele:
vstup UserInput {
Název:Řetězec
Příspěvky:[PostInput]
}
vstup PostInput {
Text:Řetězec
}
Nyní pojďme definovat mutace – operace, které upravují data uložená v našich databázích prostřednictvím našeho GraphQL API. Za tímto účelem vytvoříme typ Mutace. Jediná mutace, kterou nyní použijeme, je createUser. Protože používáme tři různé databáze, přidáváme mutaci pro každý typ databáze. Každá z mutací přijímá vstup UserInput a vrací entitu User:
Chceme také poskytnout způsob dotazování uživatelů, takže vytvoříme typ Query s jedním dotazem na typ databáze. Každý dotaz přijímá řetězec, který je UUID uživatele a vrací entitu uživatele, která obsahuje jeho jméno, UUID a kolekci všech přidružených položek:
Nakonec definujeme schéma a ukážeme na typy Query a Mutation:
schema { query: Query mutation: Mutation }
Nyní máme úplný popis našeho nového rozhraní GraphQL API! Celý soubor si můžete prohlédnout zde.
Definování obslužných programů pro GraphQL API
Nyní, když máme popis našeho GraphQL API, můžeme napsat kód, který potřebujeme pro každý dotaz a mutaci. Začneme vytvořením souboru handler.js v kořenovém adresáři projektu, hned vedle souboru schema.gql, který jsme vytvořili dříve.
Prvním úkolem handler.js je přečíst schéma:
Konstanta typeDefs nyní obsahuje definice pro naše entity GraphQL. Dále určíme, kde bude kód pro naše funkce žít. Aby bylo vše jasné, vytvoříme pro každý dotaz a mutaci samostatný soubor:
Konstanta resolverů nyní obsahuje definice všech funkcí našeho API. Naším dalším krokem je vytvoření serveru GraphQL. Pamatujete si knihovnu graphql-yoga, kterou jsme požadovali výše? Tuto knihovnu zde použijeme k vytvoření funkčního serveru GraphQL snadno a rychle:
Nakonec exportujeme obslužnou rutinu GraphQL spolu s obslužnou rutinou GraphQL Playground (což nám umožní vyzkoušet naše GraphQL API ve webovém prohlížeči):
Dobře, se souborem handler.js jsme prozatím hotovi. Dále:psaní kódu pro všechny funkce, které přistupují k databázím.
Psaní kódu pro dotazy a mutace
Nyní potřebujeme kód pro přístup k databázím a pro napájení našeho GraphQL API. V kořenovém adresáři našeho projektu vytváříme následující strukturu pro naše funkce překladače MySQL, přičemž ostatní databáze budou následovat:
Běžné dotazy
Ve složce Common naplníme soubor mysql.js tím, co budeme potřebovat pro mutaci createUser a dotaz getUser:init dotaz, abychom vytvořili tabulky pro uživatele a příspěvky, pokud ještě neexistují; a uživatelský dotaz pro vrácení dat uživatele při vytváření a dotazování uživatele. Použijeme to jak v mutaci, tak v dotazu.
Init dotaz vytvoří tabulky Users a Posts následovně:
Dotaz getUser vrátí uživatele a jeho příspěvky:
Obě tyto funkce jsou exportovány; k nim pak můžeme přistupovat v souboru handler.js.
Zápis mutace
Je čas napsat kód pro mutaci createUser, která musí přijmout jméno nového uživatele a také seznam všech příspěvků, které jim patří. K tomu vytvoříme soubor resolver/Mutation/mysql_createUser.js s jedinou exportovanou funkcí func pro mutaci:
Mutační funkce musí dělat následující věci v pořadí:
-
Připojte se k databázi pomocí přihlašovacích údajů v proměnných prostředí aplikace.
-
Vložte uživatele do databáze pomocí uživatelského jména poskytnutého jako vstup pro mutaci.
-
Vložte také všechny příspěvky spojené s uživatelem, poskytnuté jako vstup do mutace.
-
Vraťte vytvořená uživatelská data.
Zde je návod, jak toho dosáhneme v kódu:
Úplný soubor, který definuje mutaci, můžete vidět zde.
Psaní dotazu
Dotaz getUser má strukturu podobnou mutaci, kterou jsme právě napsali, ale tato je ještě jednodušší. Nyní, když je funkce getUser ve společném jmenném prostoru, již v dotazu nepotřebujeme žádné vlastní SQL. Soubor resolver/Query/mysql_getUser.js tedy vytvoříme následovně:
Celý dotaz můžete vidět v tomto souboru.
Spojení všeho dohromady v souboru serverless.yml
Udělejme krok zpět. Aktuálně máme následující:
-
Schéma GraphQL API.
-
Soubor handler.js.
-
Soubor pro běžné databázové dotazy.
-
Soubor pro každou mutaci a dotaz.
Posledním krokem je propojit toto vše dohromady prostřednictvím souboru serverless.yml. V kořenovém adresáři projektu vytvoříme prázdný serverless.yml a začneme definováním poskytovatele, regionu a běhového prostředí. Na náš projekt také aplikujeme roli LambdaRole IAM (kterou zde definujeme později):
Poté definujeme proměnné prostředí pro přihlašovací údaje databáze:
Všimněte si, že všechny proměnné odkazují na vlastní sekci, která následuje a obsahuje skutečné hodnoty proměnných. Pamatujte, že heslo je hrozné heslo pro vaši databázi a mělo by být změněno na něco bezpečnějšího (možná p@ssw0rd 😃):
Jaké jsou ty odkazy po Fn::GettAtt, ptáte se? Ty odkazují na databázové zdroje:
Soubor resource/MySqlRDSInstance.yml definuje všechny atributy instance MySQL. Jeho celý obsah naleznete zde.
Nakonec v souboru serverless.yml definujeme dvě funkce, graphql a hřiště. Funkce graphql zpracuje všechny požadavky API a koncový bod hřiště pro nás vytvoří instanci GraphQL Playground, což je skvělý způsob, jak vyzkoušet naše GraphQL API ve webovém prohlížeči:
Nyní je podpora MySQL pro naši aplikaci dokončena!
Úplný obsah souboru serverless.yml naleznete zde.
Přidání podpory Aurora a PostgreSQL
Již jsme vytvořili veškerou strukturu, kterou potřebujeme k podpoře dalších databází v tomto projektu. Abychom přidali podporu pro Auroru a Postgres, potřebujeme pouze definovat kód pro jejich mutace a dotazy, což provedeme následovně:
-
Přidejte soubor společných dotazů pro Auroru a Postgres.
-
Přidejte mutaci createUser pro obě databáze.
-
Přidejte dotaz getUser pro obě databáze.
-
Přidejte konfiguraci do souboru serverless.yml pro všechny proměnné prostředí a prostředky potřebné pro obě databáze.
V tuto chvíli máme vše, co potřebujeme k nasazení našeho GraphQL API založeného na MySQL, Aurora a PostgreSQL.
Nasazení a testování rozhraní GraphQL API
Nasazení našeho GraphQL API je jednoduché.
-
Nejprve spustíme npm install, abychom zavedli naše závislosti.
-
Poté spustíme npm run deploy, který nastaví všechny naše proměnné prostředí a provede nasazení.
-
Tento příkaz pod kapotou spouští nasazení bez serveru pomocí správného prostředí.
A je to! Ve výstupu kroku nasazení uvidíme koncový bod URL pro naši nasazenou aplikaci. Pomocí této adresy URL můžeme odesílat požadavky POST do našeho rozhraní API GraphQL a naše hřiště (se kterým si za sekundu zahrajeme) je k dispozici pomocí GET na stejné adrese URL.
Vyzkoušení API v GraphQL Playground
GraphQL Playground, což je to, co vidíte při návštěvě dané adresy URL v prohlížeči, je skvělý způsob, jak vyzkoušet naše API.
Vytvořme uživatele spuštěním následující mutace:
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 } }
V této mutaci zavoláme mysql_createUser API, dodáme text příspěvků nového uživatele a uvedeme, že jako odpověď chceme získat zpět jméno uživatele a UUID.
Vložte výše uvedený text do levé části hřiště a klikněte na tlačítko Přehrát. Vpravo uvidíte výstup dotazu:
Nyní se zeptáme na tohoto uživatele:
query { mysql_getUser(uuid: "f5593682-6bf1-466a-967d-98c7e9da844b") { Name UUID } }
To nám vrátí jméno a UUID uživatele, kterého jsme právě vytvořili. Elegantní!
Totéž můžeme udělat s ostatními backendy, PostgreSQL a Aurora. K tomu stačí nahradit jména mutace postgres_createUser nebo aurora_createUser a dotazy postgres_getUser nebo aurora_getUser. Vyzkoušejte si to sami! (Mějte na paměti, že uživatelé nejsou mezi databázemi synchronizováni, takže se budete moci dotazovat pouze na uživatele, které jste vytvořili v každé konkrétní databázi.)
Porovnání implementací MySQL, PostgreSQL a Aurora
Pro začátek, mutace a dotazy vypadají na Auroře a MySQL úplně stejně, protože Aurora je kompatibilní s MySQL. A mezi těmito dvěma a implementací Postgres jsou jen minimální rozdíly v kódu.
Ve skutečnosti je pro jednoduché případy použití největší rozdíl mezi našimi třemi databázemi v tom, že Aurora je dostupná pouze jako cluster. Nejmenší dostupná konfigurace Aurora stále obsahuje jednu repliku pouze pro čtení a jednu repliku pro zápis, takže i pro toto základní nasazení Aurora potřebujeme klastrovanou konfiguraci.
Aurora nabízí rychlejší výkon než MySQL a PostgreSQL, hlavně díky optimalizaci SSD, kterou Amazon provedl v databázovém stroji. Jak váš projekt poroste, pravděpodobně zjistíte, že Aurora nabízí lepší škálovatelnost databáze, jednodušší údržbu a lepší spolehlivost ve srovnání s výchozími konfiguracemi MySQL a PostgreSQL. Některá z těchto vylepšení však můžete provést i na MySQL a PostgreSQL, pokud vyladíte své databáze a přidáte replikaci.
Pro testovací projekty a hřiště doporučujeme MySQL nebo PostgreSQL. Ty mohou běžet na instancích db.t2.micro RDS, které jsou součástí bezplatné úrovně AWS. Aurora aktuálně nenabízí instance db.t2.micro, takže za použití Aurory pro tento testovací projekt zaplatíte o něco více.
Důležitá poznámka na závěr
Nezapomeňte odebrat nasazení bez serveru jakmile dokončíte vyzkoušení GraphQL API, abyste nemuseli platit za databázové zdroje, které již nepoužíváte.
Zásobník vytvořený v tomto příkladu můžete odstranit spuštěním npm run remove v kořenovém adresáři projektu.
Hodně štěstí při experimentování!
Souhrn
V tomto článku jsme vás provedli vytvořením jednoduchého GraphQL API pomocí tří různých databází najednou; ačkoli to není něco, co byste ve skutečnosti udělali, umožnilo nám to porovnat jednoduché implementace databází Aurora, MySQL a PostgreSQL. Viděli jsme, že implementace pro všechny tři databáze je v našem jednoduchém případě zhruba stejná, až na drobné rozdíly v syntaxi a konfiguracích nasazení.
Úplný vzorový projekt, který jsme používali, najdete v tomto repozitáři GitHubu. Nejjednodušší způsob, jak experimentovat s projektem, je naklonovat repo a nasadit jej z vašeho počítače pomocí npm run deploy.
Další příklady rozhraní GraphQL API pomocí Serverless najdete v repozitáři serverless-graphql.
Pokud byste se chtěli dozvědět více o spouštění rozhraní Serverless GraphQL API ve velkém, mohla by se vám líbit naše série článků „Spuštění škálovatelného a spolehlivého koncového bodu GraphQL pomocí Serverless“
Možná GraphQL prostě není váš jam a raději byste nasadili REST API? Máme to pro vás:několik příkladů najdete v tomto příspěvku na blogu.
otázky? Okomentujte tento příspěvek nebo vytvořte diskuzi v našem fóru.
Původně publikováno na https://www.serverless.com.