En komplet introduktion til Apollo, GraphQL toolkit

Er du interesseret i at lære JavaScript? Få min gratis e-bog på jshandbook.com

Introduktion til Apollo

I de sidste par år har GraphQL været meget populær som en alternativ tilgang til at opbygge en API over REST.

GraphQL er en fantastisk måde at lade klienten bestemme, hvilke data de vil transmitteres over netværket, snarere end at få serveren til at sende et fast datasæt.

Det giver dig også mulighed for at specificere indlejrede ressourcer, hvilket reducerer frem og tilbage, som nogle gange kræves, når du håndterer REST-API'er.

Apollo er et team og et samfund, der bygger på toppen af ​​GraphQL, og leverer forskellige værktøjer, der hjælper dig med at opbygge dine projekter.

Apollo-logo med tilladelse fra apollographql.com

De værktøjer, der leveres af Apollo, er hovedsageligt tre: Client, Server, Engine.

Apollo Client hjælper dig med at forbruge en GraphQL API med support til de mest populære frontend-webteknologier som React, Vue, Angular, Ember og Meteor. Det understøtter også native udvikling på iOS og Android.

Apollo Server er serverdelen af ​​GraphQL, der samles med din backend og sender svar tilbage til klientanmodningerne.

Apollo Engine er en hostet infrastruktur (SaaS), der fungerer som en mellemmand mellem klienten og din server, der leverer cache, præstationsrapportering, belastningsmåling, fejlsporing, skemafeltanvendelsesstatistik, historisk statistik og mange flere godbidder. Det er i øjeblikket gratis op til 1 million anmodninger om måneden, og det er den eneste del af Apollo, der ikke er open source og gratis. Det giver finansiering til open source-delen af ​​projektet.

Det er værd at bemærke, at disse tre værktøjer ikke er knyttet sammen på nogen måde, og du kan bruge bare Apollo Client til at interface med et 3. del API, eller betjene et API ved hjælp af Apollo Server uden at have en klient overhovedet, f.eks.

Nogle fordele ved at bruge Apollo

Det hele er kompatibelt med GraphQL-standardspecifikationen, så der er ingen proprietær eller inkompatibel tech i Apollo.

Men det er meget praktisk at have alle disse værktøjer sammen under ét tag som en komplet pakke til alle dine GraphQL-relaterede behov.

Apollo stræber efter at være let at bruge og let at bidrage til.

Apollo Client og Apollo Server er alle samfundsprojekter, bygget af samfundet, for samfundet. Apollo er støttet af Meteor Development Group (virksomheden bag Meteor), en meget populær JavaScript-ramme.

Apollo er fokuseret på at holde tingene enkle. Dette er noget, der er nøglen til succes for en teknologi, der ønsker at blive populær. Meget af teknologien eller rammerne eller bibliotekerne derude kan være overdreven for 99% af små eller mellemstore virksomheder, og er virkelig velegnet til de store virksomheder med meget komplekse behov.

Apollo-klient

Apollo Client er den førende JavaScript-klient for GraphQL. Da det er samfundsdrevet, er det designet til at lade dig bygge UI-komponenter, der grænser sammen med GraphQL-data - enten ved at vise disse data eller ved at udføre mutationer, når visse handlinger sker.

Du behøver ikke at ændre alt i din applikation for at gøre brug af Apollo Client. Du kan starte med kun et lille lag og en anmodning og udvide derfra.

Mest af alt er Apollo Client bygget til at være enkel, lille og fleksibel fra bunden af.

I dette indlæg skal jeg detaljerede oplysninger om processen med at bruge Apollo Client i en React-applikation.

Jeg bruger GitHub GraphQL API som en server.

Start en React-app

Jeg bruger create-react-app til at konfigurere React-appen, som er meget praktisk og tilføjer bare de blotte knogler til det, vi har brug for:

npx create-react-app myapp
npx er en kommando, der er tilgængelig i de nyeste npm-versioner. Opdater npm, hvis du ikke har denne kommando.

Start den lokale app-server med

garnstart

Åbn src / index.js:

import React fra 'react'
importer ReactDOM fra 'react-dom'
import './index.css'
importer app fra './App'
import registerServiceWorker fra './registerServiceWorker'

ReactDOM.render (, document.getElementById ('root'))
registerServiceWorker ()

og fjern alt dette indhold.

Kom godt i gang med Apollo Boost

Apollo Boost er den nemmeste måde at begynde at bruge Apollo Client på et nyt projekt. Vi installerer det ud over react-apollo og graphql.

Kør i konsollen

garn tilføj apollo-boost react-apollo graphql

eller med npm:

npm installer apollo-boost react-apollo graphql - gem

Opret et ApolloClient-objekt

Du starter med at importere ApolloClient fra apollo-client i index.js:

import {ApolloClient} fra 'apollo-client'

const client = ny ApolloClient ()

Som standard bruger Apollo Client / grafql-endepunktet på den aktuelle vært, så lad os bruge en Apollo-link til at specificere detaljerne om forbindelsen til GraphQL-serveren ved at indstille GraphQL-endepunkt URI.

Apollo Links

En Apollo Link er repræsenteret af et HttpLink-objekt, som vi importerer fra apollo-link-http.

Apollo Link giver os en måde at beskrive, hvordan vi ønsker at få resultatet af en GraphQL-operation, og hvad vi vil gøre med svaret.

Kort sagt opretter du flere Apollo Link-forekomster, der alle fungerer på en GraphQL-anmodning efter hinanden, hvilket giver det endelige resultat, du ønsker. Nogle links kan give dig muligheden for at prøve igen en anmodning, hvis det ikke lykkes, batching og meget mere.

Vi tilføjer et Apollo-link til vores Apollo Client-forekomst for at bruge GitHub GraphQL endpoint URI https://api.github.com/graphql

import {ApolloClient} fra 'apollo-client'
import {HttpLink} fra 'apollo-link-http'

const client = ny ApolloClient ({
  link: nyt HttpLink ({uri: 'https://api.github.com/graphql'})
})

Caching

Vi er ikke færdige endnu. Inden vi har et arbejdseksempel, skal vi også fortælle ApolloClient, hvilken cache-strategi der skal bruges: InMemoryCache er standard, og det er en god en, der skal startes med.

import {ApolloClient} fra 'apollo-client'
import {HttpLink} fra 'apollo-link-http'
import {InMemoryCache} fra 'apollo-cache-inmemory'

const client = ny ApolloClient ({
  link: nyt HttpLink ({uri: 'https://api.github.com/graphql'}),
  cache: ny InMemoryCache ()
})

Brug ApolloProvider

Nu skal vi forbinde Apollo-klienten til vores komponenttræ. Vi gør det ved hjælp af ApolloProvider ved at indpakke vores applikationskomponent i den vigtigste React-fil:

import React fra 'react'
importer ReactDOM fra 'react-dom'
import {ApolloClient} fra 'apollo-client'
import {HttpLink} fra 'apollo-link-http'
import {InMemoryCache} fra 'apollo-cache-inmemory'
import {ApolloProvider} fra 'react-apollo'

importer app fra './App'

const client = ny ApolloClient ({
  link: nyt HttpLink ({uri: 'https://api.github.com/graphql'}),
  cache: ny InMemoryCache ()
})

ReactDOM.render (
  
    
  ,
  document.getElementById ( 'root')
)

Dette er nok til at gengive standardskærmen til oprettelse-reaktion-app med Apollo Client initialiseret:

Gql-skabelonmærket

Vi er nu klar til at gøre noget med Apollo Client, og vi vil hente nogle data fra GitHub API og gengive dem.

For at gøre det er vi nødt til at importere gql-skabelonmærket:

importer gql fra 'graphql-tag'

Enhver GraphQL-forespørgsel vil blive bygget ved hjælp af dette skabelonmærke på denne måde:

const query = gql`
  forespørgsel {
    ...
  }
`

Udfør en GraphQL-anmodning

gql var den sidste vare, vi havde brug for i vores værktøjssæt.

Vi er nu klar til at gøre noget med Apollo Client, og vi vil hente nogle data fra GitHub API og gengive dem.

Få et adgangstoken til API'en

Den første ting at gøre er at få et personlig adgangstoken fra GitHub.

GitHub gør det let ved at tilvejebringe en grænseflade, hvorfra du vælger enhver tilladelse, du muligvis har brug for:

Af hensyn til dette eksempelvejledning behøver du ikke nogen af ​​disse tilladelser. De er beregnet til adgang til private brugerdata, men vi vil bare spørge de offentlige depotdata.

Det token, du får, er et OAuth 2.0-bærertoken.

Du kan nemt teste det ved at køre fra kommandolinjen:

$ krøllet -H "Autorisation: bærer *** _ YOUR_TOKEN_HERE _ ***" -X POST -d "\
 {\
   \ "forespørgsel \": \ "forespørgsel {viewer {login}} \" \
 } \
"https://api.github.com/graphql

hvilket skulle give dig resultatet

{ "Data": { "viewer": { "login": "*** _ YOUR_LOGIN_NAME _ ***"}}}

eller

{
  "meddelelse": "Dårlige legitimationsoplysninger",
  "dokumentation_url": "https://developer.github.com/v4"
}

hvis noget gik galt.

Brug en Apollo-link til at godkende

Så vi er nødt til at sende autorisationshovedet sammen med vores GraphQL-anmodning, ligesom vi gjorde i curl-anmodningen ovenfor.

Vi kan gøre dette med Apollo Client ved at oprette en Apollo Link middleware. Start med installation af apollo-link-context:

npm installerer apollo-link-kontekst

Denne pakke giver os mulighed for at tilføje en godkendelsesmekanisme ved at indstille konteksten af ​​vores anmodninger.

Vi kan bruge den i denne kode ved at henvise til setContext-funktionen på denne måde:

const autorLink = setContext ((_, {headers}) => {
  const token = '*** YOUR_TOKEN **'

  Vend tilbage {
    overskrifter: {
      ... overskrifter,
      autorisation: `Bærer $ {token}`
    }
  }
})

og når vi først har fået denne nye Apollo Link, kan vi komponere den med den HttpLink, vi allerede havde, ved at bruge concat () -metoden på et link:

const link = authLink.concat (httpLink)

Her er den fulde kode for src / index.js-filen med den kode, vi har lige nu:

import React fra 'react'
importer ReactDOM fra 'react-dom'
import {ApolloClient} fra 'apollo-client'
import {HttpLink} fra 'apollo-link-http'
import {InMemoryCache} fra 'apollo-cache-inmemory'
import {ApolloProvider} fra 'react-apollo'
import {setContext} fra 'apollo-link-context'
importer gql fra 'graphql-tag'

importer app fra './App'

const httpLink = nyt HttpLink ({uri: 'https://api.github.com/graphql'})

const autorLink = setContext ((_, {headers}) => {
  const token = '*** YOUR_TOKEN **'

  Vend tilbage {
    overskrifter: {
      ... overskrifter,
      autorisation: `Bærer $ {token}`
    }
  }
})

const link = authLink.concat (httpLink)

const client = ny ApolloClient ({
  link: link,
  cache: ny InMemoryCache ()
})

ReactDOM.render (
  
    
  ,
  document.getElementById ( 'root')
)
ADVARSEL Husk, at denne kode er et eksempel til uddannelsesmæssige formål. Det udsætter dit GitHub GraphQL API for verden at se i din frontend-vendende kode. Produktionskode skal holde dette token privat.

Vi kan nu indstille den første GraphQL-anmodning i bunden af ​​denne fil, og denne eksempelspørgsmål beder om navnene og ejerne af de 10 mest populære oplagringssteder med mere end 50 k stjerner:

const POPULAR_REPOSITORIES_LIST = gql`
{
  søgning (forespørgsel: "stjerner:> 50000", type: REPOSITORY, først: 10) {
    repositoryCount
    kanter {
      node {
        ... på depot {
          navn
          ejer {
            Log på
          }
          stargazers {
            TOTALCOUNT
          }
        }
      }
    }
  }
}
`

client.query ({forespørgsel: POPULAR_REPOSITORIES_LIST}). derefter (console.log)

At køre denne kode med succes returnerer resultatet af vores forespørgsel i browserkonsollen:

Gengiv et GraphQL-forespørgselsresultat, der er sat i en komponent

Hvad vi har set indtil nu, er allerede cool. Hvad der er endnu køligere bruger GraphQL resultatsæt til at gengive dine komponenter.

Vi lader Apollo Client have byrden (eller glæden) eller hente dataene og håndtere alle de lave niveauer. Dette lader os fokusere på at vise dataene ved hjælp af den grafql-komponentforstærker, der tilbydes af react-apollo:

import React fra 'react'
import {graphql} fra 'react-apollo'
import {gql} fra 'apollo-boost'

const POPULAR_REPOSITORIES_LIST = gql`
{
  søgning (forespørgsel: "stjerner:> 50000", type: REPOSITORY, først: 10) {
    repositoryCount
    kanter {
      node {
        ... på depot {
          navn
          ejer {
            Log på
          }
          stargazers {
            TOTALCOUNT
          }
        }
      }
    }
  }
}
`

const App = grafql (POPULAR_REPOSITORIES_LIST) (rekvisitter =>
  
        {props.data.loading? '': props.data.search.edges.map ((række, i) =>       
  •         {row.node.owner.login} / {row.node.name}: {''}                    {Row.node.stargazers.totalCount}                     )}    ) eksporter standardapp

Her er resultatet af vores forespørgsel, der er gengivet i komponenten

Apollo Server

En GraphQL-server har jobbet med at acceptere indkommende anmodninger på et slutpunkt, fortolke anmodningen og finde alle data, der er nødvendige for at opfylde klientens behov.

Der er masser af forskellige GraphQL-serverimplementeringer til alle mulige sprog.

Apollo Server er en GraphQL-serverimplementering til JavaScript, især til Node.js-platformen.

Det understøtter mange populære Node.js-rammer, herunder:

  • Hurtig
  • Hapi
  • Koa
  • Restify

Apollo-serveren giver os dybest set tre ting:

  • En måde at beskrive vores data med et skema.
  • Rammerne for opløsere, som er funktioner, vi skriver for at hente de data, der er nødvendige for at opfylde en anmodning.
  • Det letter håndtering af godkendelse af vores API.

For at lære det grundlæggende om Apollo Server vil vi ikke bruge nogen af ​​de understøttede Node.js-rammer. I stedet bruger vi noget, der er bygget af Apollo-teamet, noget virkelig godt, som vil være basen i vores læring: Launchpad.

Affyringsrampe

Launchpad er et projekt, der er en del af Apollo-paraplyen af ​​produkter, og det er et temmelig fantastisk værktøj, der giver os mulighed for at skrive kode på skyen og oprette en en Apollo-server online, ligesom vi vil køre et kodestykke på Codepen, JSFiddle eller JSBin.

Bortset fra at i stedet for at opbygge et visuelt værktøj, der vil blive isoleret der, og betydet som et udstillingsvindue eller som et læringsværktøj, laver vi med Launchpad et GraphQL API. Det bliver offentligt tilgængeligt.

Hvert projekt på Launchpad kaldes pad og har sin GraphQL endpoint URL, som:

https://1jzxrj129.lp.gql.zone/graphql

Når du har opbygget en pude, giver Launchpad dig muligheden for at downloade den fulde kode for Node.js-appen, der kører den, og du skal bare køre npm installation og npm begynde at få en lokal kopi af din Apollo GraphQL Server.

For at opsummere er det et godt værktøj til at lære, dele og prototype.

Apollo-serveren Hello World

Hver gang du opretter en ny startpude, får du præsenteret Hello, World! af Apollo Server. Lad os dykke ned i det.

Først importerer du funktionen makeExecutableSchema fra grafql-værktøjer.

import {makeExecutableSchema} fra 'graphql-tools'

Denne funktion bruges til at oprette et GraphQLSchema-objekt ved at give det en skemadefinition (skrevet på GraphQL-skemaets sprog) og et sæt opløsere.

En skema-definition er en bogstavelig skabelonstreng, der indeholder beskrivelsen af ​​vores forespørgsel og de typer, der er knyttet til hvert felt:

const typeDefs = `
  type forespørgsel {
    hej: streng
  }
`

En resolver er et objekt, der kortlægger felter i skemaet til resolverfunktioner. Det er i stand til at opsøge data for at svare på en forespørgsel.

Her er en simpel resolver, der indeholder resolverfunktionen til hejefeltet, som ganske enkelt returnerer Hello-verdenen! snor:

const resolvers = {
  Forespørgsel: {
    hej: (rod, args, kontekst) => {
      vende tilbage 'Hej verden!'
    }
  }
}

I betragtning af disse to elementer, skemadefinitionen og opløseren, bruger vi funktionen makeExecutableSchema, vi importerede tidligere, for at få et GraphQLSchema-objekt, som vi tildeler skemakonst.

eksport const schema = makeExecutableSchema ({typeDefs, resolvers})

Dette er alt hvad du har brug for for at servere en simpel skrivebeskyttet API. Launchpad tager sig af de små detaljer.

Her er den fulde kode til det enkle Hello World-eksempel:

import {makeExecutableSchema} fra 'graphql-tools'

const typeDefs = `
  type forespørgsel {
    hej: streng
  }
`

const resolvers = {
  Forespørgsel: {
    hej: (rod, args, kontekst) => {
      vende tilbage 'Hej verden!'
    }
  }
}

eksport const schema = makeExecutableSchema ({
  typeDefs,
  resolvere
})

Launchpad giver et fantastisk indbygget værktøj til at forbruge API:

Og som jeg sagde tidligere, API'en er offentligt tilgængelig, så du skal bare logge ind og gemme din pude.

Jeg lavede en pude, der afslører dens slutpunkt på https://kqwwkp0pr7.lp.gql.zone/graphql, så lad os prøve det ved hjælp af krøll fra kommandolinjen:

$ krølle \
  -X POST \
  -H "Indholdstype: ansøgning / json" \
  --data '{"query": "{hej}"}' \
  https://kqwwkp0pr7.lp.gql.zone/graphql

hvilket med succes giver os det resultat, vi forventer:

{
  "data": {
    "hallo": "Hej verden!"
  }
}

Kør GraphQL Server lokalt

Vi nævnte, at alt, hvad du opretter på Launchpad, kan downloades, så lad os gå videre.

Pakken er sammensat af to filer. Den første, schema.js, er det, vi har ovenfor.

Den anden, server.js, var usynlig i Launchpad, og det er det, der giver den underliggende Apollo Server-funktionalitet, drevet af Express, den populære Node.js-ramme.

Det er ikke det enkleste eksempel på en Apollo Server-opsætning, så for at forklare, vil jeg erstatte det med et mere enkelt eksempel (men føl dig fri til at studere det, når du har forstået det grundlæggende).

Din første Apollo Server-kode

Kør først npm installation og npm start på den startkode, du har downloadet.

Den nodeserver, vi initialiserede, bruger fortrinsvis nodemon til at genstarte serveren, når filerne ændres, så når du ændrer koden, genstartes serveren med dine ændringer anvendt.

Tilføj denne kode i server.js:

const express = kræver ('express')
const bodyParser = kræver ('body-parser')
const {graphqlExpress} = kræve ('apollo-server-express')
const {schema} = kræve ('./ schema')

const server = express ()

server.use ('/ grafql', bodyParser.json (), grafqlExpress ({schema}))

server.listen (3000, () => {
  console.log ('Grafisk lytning på http: // localhost: 3000 / grafql')
})

Med kun 11 linjer er dette meget enklere end serveren, der er oprettet af Launchpad, fordi vi fjernede alle de ting, der gjorde denne kode mere fleksibel efter deres behov.

Kodning tvinger dig til at tage hårde beslutninger: hvor meget fleksibilitet har du brug for nu? Hvor vigtigt er det at have ren, forståelig kode, som du kan hente seks måneder fra nu og let justere, eller videregive til andre udviklere og teammedlemmer, så de kan være produktive på så lidt tid som nødvendigt?

Dette er, hvad koden gør:

Vi importerer først et par biblioteker, vi vil bruge.

  • udtrykke, hvilket får den underliggende netværksfunktionalitet til at eksponere slutpunktet
  • bodyParser er Node body parsing middleware
  • graphqlExpress er Apollo Server-objektet til Express
const express = kræver ('express')
const bodyParser = kræver ('body-parser')
const {graphqlExpress} = kræve ('apollo-server-express')

Dernæst importerer vi GraphQLSchema-objektet, vi oprettede i schema.js-filen ovenfor som skema:

const {schema} = kræve ('./ schema')

Her er nogle standard Express-sæt, og vi initialiserer bare en server på port 3000

const server = express ()

Nu er vi klar til at initialisere Apollo Server:

graphqlExpress ({schema})

og vi videregiver det som et tilbagekald til vores slutpunkt til HTTP JSON-anmodninger:

server.use ('/ grafql', bodyParser.json (), grafqlExpress ({schema}))

Alt, hvad vi har brug for nu, er at starte Express:

server.listen (3000, () => {
  console.log ('Grafisk lytning på http: // localhost: 3000 / grafql')
})

Tilføj et GraphiQL-endpoint

Hvis du bruger GraphiQL, kan du nemt tilføje et / grafiql-endepunkt for at forbruge med den interaktive GraphiQL-browser i IDE:

server.use ('/ grafiql', grafiqlExpress ({
  endpointURL: '/ graphql',
  forespørgsel: ``
}))

Vi har nu bare brug for at starte Express-serveren:

server.listen (PORT, () => {
  console.log ('Grafisk lytning på http: // localhost: 3000 / grafql')
  console.log ('GraphiQL lytter på http: // localhost: 3000 / grafiql')
})

Du kan teste det ved hjælp af krølle igen:

$ krølle \
  -X POST \
  -H "Indholdstype: ansøgning / json" \
  --data '{"query": "{hej}"}' \
  http: // localhost: 3000 / graphql

Dette giver dig det samme resultat som ovenfor, hvor du kaldte Launchpad-serverne:

{
  "data": {
    "hallo": "Hej verden!"
  }
}
Er du interesseret i at lære JavaScript? Få min gratis e-bog på jshandbook.com