Cum se construiesc API-uri GraphQL și REST fără server folosind AWS Amplify

AWS Amplify permite dezvoltatorilor să creeze rapid și să se conecteze la servicii puternice din cloud. În tutorialul anterior, ați învățat cum să configurați proiectul Amplificați într-un proiect React și cum să utilizați autentificarea, stocarea S3 și găzduirea. Dacă aveți nevoie de o introducere la AWS Amplify, asigurați-vă că verificați mai întâi postarea.

În acest post, vom merge mai departe cu React și AWS Amplify, explorând caracteristici precum un strat de date GraphQL gestionat și funcții lambda.

Adăugarea unui API GraphQL

Să ne uităm cum să adăugăm un API AWS AppSync GraphQL la proiectul nostru și să îl folosim din cadrul proiectului nostru.

API-ul pe care îl vom crea va fi un API pentru restaurant pentru a ne ține pasul cu restaurantele pe care le place sau pe care le-ar plăcea să le viziteze.

Pentru a adăuga API-ul GraphQL la proiectul nostru, putem folosi următoarea comandă:

amplifica adăugați api

Vi se va cere să răspundeți la câteva întrebări de configurare. Selectați următoarele opțiuni:

  • serviciu tip: GraphQL
  • Nume API: TutsGraphQLAPI
  • tipul de autorizare: Cheia API
  • schema grafică adnotată: N
  • ghida crearea de scheme: Y
  • Ce descrie cel mai bine proiectul dvs.? Obiect unic cu câmpuri (de ex. "Todo" cu ID, nume, descriere)
  • Doriți să editați schema acum? Y

Când vi se solicită, actualizați schema la următoarele, apoi salvați fișierul:

// localizat la amplificare-web-app / amplificare / backend / api / TutsGraphQLAPI / schema.graphql tip Restaurant @model id: ID! Nume: String! descriere: String

Acest lucru creează doar un singur tip de date-Restaurant-cu câmpurile de identificare și nume necesare, precum și cu o descriere opțională.

Apoi, trimiteți actualizările la contul nostru:

amplifica împinge

Acum, API-ul a fost creat!

Ce sa întâmplat aici? AWS Amplify a folosit biblioteca încorporată GraphQL Transform pentru a crea un API complet GraphQL, inclusiv schemă suplimentară, rezolvatori și o sursă de date.

Pentru a vedea noul API AWS AppSync în orice moment după crearea acestuia, puteți accesa tabloul de bord la adresa https://console.aws.amazon.com/appsync și faceți clic pe API-ul care tocmai a fost creat (asigurați-vă că regiunea dvs. este setat corect). Din tabloul de bord AWS AppSync, puteți vizualiza configurația API și puteți efectua interogări și mutații pe API.

Executarea mutațiilor GraphQL

Apoi, hai să interacționăm cu API din aplicația noastră React.

Primul lucru pe care ne-ar plăcea să-l facem este să creăm o mutație. În GraphQL, mutațiile sunt echivalente cu REST A PUNE, APĂSAȚI și ȘTERGE operațiuni. Pentru că nu avem date în baza noastră de date, vom crea o mutație pentru a crea un nou articol de restaurant.

Pentru a face acest lucru, vom importa API-ul și graphqlOperation de la AWS Amplify, definind o mutație și apoi executând mutația.

Să ne uităm la o aplicație de exemplu care implementează o mutație. În App.js, mai întâi vom importa React, aplicația CSS și componentele AWS Amplify necesare.

import React, Component de la "reacție"; import "./App.css"; import withAuthenticator din 'aws-amplify-react' import API, graphqlOperation de la 'aws-amplify'

Apoi, definim o mutație pentru a crea un restaurant. Specificăm că mutația acceptă un nume și o descriere și este denumită createRestaurant. Această mutație a fost definită automat când am creat Restaurant schema de mai sus. Rețineți că mutația este specificată în GraphQL - o limbă de interogare specifică domeniului.

const CreareRestaurant = 'mutație ($ name: String !, $ description: String) createRestaurant (introducere: name: $ description description: description description

Acum, creăm componenta noastră de aplicație.

Aplicația de clasă extinde componenta // a crea starea inițială de stare = name: ", description:" // starea actualizării atunci când utilizatorul introduce intrări onChange = e => this.setState e.target.name]: .target.value) // definește funcția pentru a executa mutația // a face componenta

Apoi, încă în cadrul App componente, definim o funcție pentru executarea mutației. Aceasta execută mutația apelând API.graphql, transmiterea mutației și a datelor.

 // definește funcția de execuție a mutației createRestaurant = async () => if (this.state.name === "|| this.state.description ===") returnează const restaurant = name: thisstatestate . nume, descriere: this.state.description așteaptă API.graphql (graphqlOperation (createRestaurant, restaurant)) this.setState (nume: ", description:") console.log (err) console.log ("eroare la crearea restaurantului ...")

Apoi, facem componenta, conectându-ne funcția de manipulare a schimbării și funcțiile de mutație.

 // render componenta rendere () retur ( 
)

În cele din urmă, exportim App componentă, cu autentificare.

export implicit cuAuthenticator (App, includeGreetings: true);

Ar trebui să puteți rula acest cod și să începeți să creați noi elemente de restaurant în API.

Pentru a vedea sursa actuală de date pentru a vedea dacă există date, deschideți tabloul de bord AppWorks, alegeți API-ul, faceți clic pe Surse de date în meniul din stânga, apoi faceți clic pe Numele resursei. Aceasta va deschide tabelul Amazon DynamoDB. În tabel, puteți vizualiza datele din Articole fila.

Rularea interogărilor GraphQL

Apoi, să examinăm cum să interogăm datele din API. Vom implementa acest lucru în trei etape:

  1. defini o interogare
  2. executați interogarea când se încarcă aplicația
  3. salvați rezultatul din interogare în starea noastră și faceți-l în interfața de utilizare

Mai întâi, să definim interogarea în o componentă nouă. Încă o dată, folosim limba GraphQL pentru a specifica interogarea. Folosim listRestaurants interogare care a fost definită automat când am apăsat Restaurante schemă. Fragmentul de mai jos specifică faptul că așteptăm o listă de articole, fiecare cu un id, nume și descriere.

const ListRestaurants = 'interogare listRestaurants elemente nume nume descriere

Apoi, trebuie să adăugăm o stare inițială suplimentară pentru a păstra seria de restaurante returnate de pe server.

state = nume: ", descriere:", restaurante: []

Va trebui, de asemenea, să adăugăm o componentDidMount ciclului de viață pentru interogarea datelor de pe serverul GraphQL. Această metodă de asincronizare va actualiza starea componentei atunci când lista de restaurante va fi returnată de pe server.

async componentDidMount () try const restaurante = asteapta API.graphql (graphqlOperation (ListRestaurants)) console.log (restaurante, restaurante) this.setState (restaurante: restaurants.data.listRestaurants.items err) console.log ("eroare la preluarea datelor:", err)

În cele din urmă, vom crea o componentă care să hărțuiască restaurante array de la starea componentei la HTML.

this.state.restaurants.map ((r, i) => ( 

R.name

R.description

))

Acum, când vom rula aplicația, vom vedea că datele din API sunt redate într-o listă de pe ecran. Cu toate acestea, aplicația nu va afișa nicio modificare atunci când datele sunt actualizate - de exemplu, atunci când adăugați un nou restaurant. 

Deci, pentru început, hai să actualizăm createRestaurant pentru a oferi un răspuns optimist la interfața utilizator. În momentul în care creăm un element nou, baza de date se actualizează, dar interfața de utilizare nu cunoaște încă elementul nou. Pentru a rezolva aceasta, vom actualiza matricea restaurantului în createRestaurant prin adăugarea elementului nou în matrice:

createRestaurant = async () => if (this.state.name === "|| this.state.description ===") returnează const restaurant = name: this.state.name, description: this. (nume, descriere, restaurante) așteaptă API.graphql (graphqlOperation (CreateRestaurant, restaurant)) console.log (' restaurantul a fost creat cu succes! ') captură (err) console.log ("eroare la crearea restaurantului ...")

Abonamente de date în timp real

Apoi, dorim să putem lucra cu date în timp real. În GraphQL, abonamentele vă permit să ascultați date în timp real. Atunci când sunt disponibile date noi, abonamentul este declanșat și noile date sunt transmise prin abonament. Depinde de noi pe partea clientului să rezolvăm aceste noi date.

În aplicația noastră, vă vom abona la o serie de restaurante și vom crea un onCreateRestaurant abonament care va declanșa în orice moment crearea unui nou restaurant. Apoi vom lua noul articol din abonament, vom actualiza tabloul nostru existent și vom apela setState pentru a re-face UI cu noile date.

La fel ca pentru mutații și interogări, începem prin definirea abonamentului în limba specifică domeniului GraphQL.

// definește abonamentul const OnCreateRestaurant = 'abonament onCreateRestaurant descriere nume nume'

Abonamentul va fi creat în componentDidMount metoda ciclului de viață fie înainte, fie după interogarea GraphQL pe care am stabilit-o deja:

async componentDidMount () try const restaurante = asteapta API.graphql (graphqlOperation (ListRestaurants)) console.log (restaurante, restaurante) this.setState (restaurante: restaurants.data.listRestaurants.items err) console.log ('eroare la preluarea datelor:', err) API.graphql (graphqlOperation (OnCreateRestaurant)) .subscribe (next: eventData = 'data:', data) const restaurante = [... this.state.restaurants.filter (r => r.name! == data.name && r.description! == data.description), data] this.setState ( restaurante)

Acum, dacă deschideți două ferestre de browser, ar trebui să puteți crea o mutație într-un singur ecran și să vedeți că actualizarea are loc pe toate celelalte ecrane.

Dacă te uiți la .filtru metoda pe care am folosit-o la crearea noii mese de restaurante în abonament, puteți vedea că verificăm dacă există duplicate care conțin același nume și aceeași descriere. Poate că o modalitate mai bună de a face acest lucru în producție ar fi să creeze un ID client unic care este, de asemenea, stocat în baza de date și filtru pe baza acelui identificator.

Crearea unui API REST cu AWS Lambda

GraphQL este o tehnologie minunată, dar uneori proiectul nostru va necesita crearea unui API tradițional REST. Cu AWS Lambda și Amplify, este de asemenea ușor să creați API REST fără server folosind CLI.

Când am creat API-ul GraphQL, am folosit amplifica crea api comanda. Această comandă ne oferă opțiunea de a crea fie un GraphQL API, fie un API REST. API-ul REST poate fi configurat să utilizeze fie o funcție autonomă serverless Express, fie o funcție JavaScript fără server care este preconfigurată pentru a lucra cu operațiile Amazon DynamoDB CRUD.

Opțiunea pe care o vom folosi pentru acest API este o funcție Expressless fără server.

Să mergem mai departe și să adăugăm noua caracteristică:

amplifica adăugați api

Ca de obicei, aceasta vă va solicita să completați unele detalii de configurare. Oferiți următoarele opțiuni:

  • serviciu tip: ODIHNĂ
  • introduceți un nume de resursă care va fi utilizat în cadrul proiectului: de ex. amplifyrestapi
  • introduceți o cale pentru punctele finale REST: de ex. /oameni
  • Lambda sursa: Creați o nouă funcție Lambda
  • AWS Numele funcției Lambda: amplifyrestapifunction
  • funcție de șablon: Serverless funcția expres (integrare cu Gateway API Amazon)
  • editați funcția lambda locală acum? Y

Acum, veți putea edita funcția lambda la nivel local. În fișier, vom înlocui existența app.get ( '/') persoane cu următoarele metode:

/ / amplifyrestapi / src / app.js app.get ('/ people', funcția (req, res) const people = [name: "Nader" nume: "Amanda", nume: "Chris", nume: "] res.json (succes: true, people);

Aceasta returnează o listă constantă de nume pentru scopuri demo. Salvați acest fișier și continuați cu următoarele răspunsuri:

  • restricționa accesul la API? da
  • care ar trebui să aibă acces? Numai utilizatorii autentificați
  • ce fel de acces doriți pentru utilizatorii autentificați? citit
  • adăugați o altă cale? N

Acest lucru a creat o nouă funcție Lambda la nivel local pe care o vom putea actualiza și împinge în cont după cum este necesar. Codul pentru această funcție lambda este situat la amplifica / backend / funcția / amplifyrestapi / src.

Acum, să împingem actualizările la contul nostru:

amplifica împinge

Cererea API-ului REST de la client

Acum, funcția noastră Lambda este în plină desfășurare și putem începe să interacționăm cu ea!

Mai întâi, hai să căutăm datele din noul API și să le afișăm în interfața noastră. Pentru a face acest lucru, vom folosi API-ul clasa de la Amplify, chemând API.get. În secțiunea anterioară, am folosit API.graphql pentru a face cereri pentru API-ul GraphQL, dar există multe metode disponibile în clasa API. Puteți afla mai multe despre clasa API în documentele oficiale.

import API de la 'aws-amplify' // 1. în starea inițială, creați o matrice goală de oameni state = people: [] // 2. în componentDidMount, vom prelua aceste date utilizând încercarea de clasă API con peopleData = await API.get ('amplifyrestapi', '/ people') this.setState (people: peopleData.people) catch (err) console.log / 3. reda datele utilizatorilor către UI în metoda rendering this.state.people.map ((person, index) => ( 

Person.name

))

Acum, ar trebui să putem rula aplicația, să preluăm datele despre persoane din API și să le punem pe ecran.

Actualizarea unei funcții Lambda din CLI

Pe lângă crearea unei noi funcții Lambda, putem de asemenea să actualizăm funcția Lambda din CLI.

Să modificăm funcția pentru a lovi un API și pentru a prelua datele în loc de constantele hardcoding. Pentru a face acest lucru, vom folosi Axios bibliotecă pentru efectuarea cererilor HTTP și vom prelua datele din API-ul Star Wars.

Pentru a folosi Axios, va trebui să navigăm la amplifica / backend / funcția / amplifyrestapi / srcși instalați-l acolo. Axios este instalat în dosarul de proiect al funcției Lambda, nu în directorul principal al aplicației, deoarece va funcționa în partea de server funcția Lambda.

fire adaugă Axios # sau npm instalează Axios

Acum că Axios este instalat, vom actualiza funcția Lambda pentru a prelua date din API-ul Star Wars:

var axios = necesita ('axios') app.get ('/ people', function (req, res) axios.get ('https://swapi.co/api/people/'). res.json (succes: true, people: response.data.results)) .catch (eroare => res.json (succes: false, eroare)));

Acum, salvați fișierul și executați amplifica împinge din dosarul principal al proiectului pentru a vă actualiza funcția Lambda în cloud:

amplifica împinge

Acum API-ul nostru este actualizat și gata de plecare!

Când actualizăm aplicația, ar trebui să vedem acum datele returnate din API-ul Star Wars.

Concluzie

În această serie, ați învățat cum să începeți cu AWS Amplify și adăugați-o la proiectul dvs. React, precum și cum să adăugați autentificarea, stocarea, găzduirea și un API GraphQL sau REST - toate fără a fi necesar să codificați manual sau să furnizați un server . Aceasta este o mulțime de putere pentru dezvoltatorii de aplicații! 

Sper că aceste postări v-au inspirat să construiți propriile aplicații web fără server folosind tehnologia fără server și AWS Amplify! Spuneți-ne ce credeți în comentariile de mai jos.

Cod