Een complete introductie tot Apollo, de GraphQL-toolkit

Wilt u JavaScript leren? Ontvang mijn gratis ebook op jshandbook.com

Inleiding tot Apollo

In de afgelopen jaren is GraphQL enorm populair geworden als een alternatieve benadering voor het bouwen van een API via REST.

GraphQL is een geweldige manier om de klant te laten beslissen welke gegevens ze via het netwerk willen verzenden, in plaats van de server een vaste set gegevens te laten verzenden.

Ook kunt u geneste bronnen opgeven, waardoor het heen en weer schakelen dat soms nodig is bij het omgaan met REST API's.

Apollo is een team en community die voortbouwt op GraphQL en verschillende tools biedt waarmee u uw projecten kunt bouwen.

Apollo-logo met dank aan apollographql.com

De tools die door Apollo worden aangeboden zijn hoofdzakelijk drie: Client, Server, Engine.

Apollo Client helpt u bij het consumeren van een GraphQL API, met ondersteuning voor de meest populaire front-end webtechnologieën zoals React, Vue, Angular, Ember en Meteor. Het ondersteunt ook native ontwikkeling op iOS en Android.

Apollo Server is het servergedeelte van GraphQL, dat interfacet met uw backend en antwoorden terugstuurt naar de clientverzoeken.

Apollo Engine is een gehoste infrastructuur (SaaS) die fungeert als een tussenpersoon tussen de client en uw server, die caching, prestatierapportage, belastingsmeting, fouttracking, gebruiksstatistieken van schemavelden, historische statistieken en nog veel meer goodies biedt. Het is momenteel gratis tot 1 miljoen aanvragen per maand, en het is het enige deel van Apollo dat niet open source en gratis is. Het biedt financiering voor het open source deel van het project.

Het is vermeldenswaard dat deze drie hulpprogramma's op geen enkele manier aan elkaar zijn gekoppeld en u kunt alleen Apollo Client gebruiken om te communiceren met een API van het derde deel, of een API bedienen met behulp van Apollo Server, bijvoorbeeld zonder een client.

Enkele voordelen van het gebruik van Apollo

Het is allemaal compatibel met de GraphQL-standaardspecificatie, dus er is geen eigen of incompatibele technologie in Apollo.

Maar het is erg handig om al die tools onder één dak te hebben als een complete suite voor al uw GraphQL-gerelateerde behoeften.

Apollo streeft ernaar eenvoudig te zijn en gemakkelijk bij te dragen.

Apollo Client en Apollo Server zijn allemaal gemeenschapsprojecten, gebouwd door de gemeenschap, voor de gemeenschap. Apollo wordt ondersteund door de Meteor Development Group (het bedrijf achter Meteor), een zeer populair JavaScript-framework.

Apollo is erop gericht dingen eenvoudig te houden. Dit is iets belangrijks voor het succes van een technologie die populair wil worden. Veel van de technologie of frameworks of bibliotheken die er zijn, kunnen voor 99% van de kleine of middelgrote bedrijven overkill zijn en zijn echt geschikt voor de grote bedrijven met zeer complexe behoeften.

Apollo-client

Apollo Client is de toonaangevende JavaScript-client voor GraphQL. Omdat het door de gemeenschap wordt aangestuurd, is het ontworpen om u UI-componenten te laten bouwen die samenwerken met GraphQL-gegevens - hetzij bij het weergeven van die gegevens, hetzij bij het uitvoeren van mutaties wanneer bepaalde acties plaatsvinden.

U hoeft niet alles in uw toepassing te wijzigen om gebruik te kunnen maken van Apollo Client. U kunt beginnen met slechts één kleine laag en één verzoek en vanaf daar uitbreiden.

Bovenal is Apollo Client vanaf de grond opgebouwd om eenvoudig, klein en flexibel te zijn.

In dit bericht ga ik in detail in op het proces van het gebruik van Apollo Client in een React-toepassing.

Ik gebruik de GitHub GraphQL API als server.

Start een React-app

Ik gebruik de create-react-app om de React-app in te stellen, wat erg handig is en alleen de kale delen toevoegt van wat we nodig hebben:

npx maken-reageren-app myapp
npx is een opdracht die beschikbaar is in de nieuwste npm-versies. Werk npm bij als u deze opdracht niet hebt.

Start de app-lokale server met

garen start

Open src / index.js:

importeren Reageren van 'reageren'
ReactDOM importeren uit 'react-dom'
import './index.css'
app importeren uit './App'
registerServiceWorker importeren uit './registerServiceWorker'

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

en verwijder al deze inhoud.

Ga aan de slag met Apollo Boost

Apollo Boost is de gemakkelijkste manier om Apollo Client te gebruiken voor een nieuw project. We zullen dat installeren naast react-apollo en graphql.

Voer in de console uit

garen voeg apollo-boost react-apollo graphql toe

of met npm:

npm installeer apollo-boost react-apollo graphql - opslaan

Maak een ApolloClient-object

U begint met het importeren van ApolloClient vanuit apollo-client in index.js:

importeer {ApolloClient} van 'apollo-client'

const client = nieuwe ApolloClient ()

Standaard gebruikt Apollo Client het / graphql-eindpunt op de huidige host, dus laten we een Apollo Link gebruiken om de details van de verbinding met de GraphQL-server op te geven door de GraphQL-eindpunt-URI in te stellen.

Apollo Links

Een Apollo Link wordt vertegenwoordigd door een HttpLink-object, dat we importeren van apollo-link-http.

Apollo Link biedt ons een manier om te beschrijven hoe we het resultaat van een GraphQL-bewerking willen krijgen en wat we met de reactie willen doen.

Kortom, u maakt meerdere Apollo Link-exemplaren die allemaal na elkaar reageren op een GraphQL-verzoek en het gewenste eindresultaat opleveren. Sommige links kunnen u de optie geven om een ​​aanvraag opnieuw te proberen als deze niet succesvol is, batching en nog veel meer.

We voegen een Apollo Link toe aan onze Apollo Client-instantie om de GitHub GraphQL-eindpunt-URI te gebruiken https://api.github.com/graphql

importeer {ApolloClient} van 'apollo-client'
importeer {HttpLink} uit 'apollo-link-http'

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

caching

We zijn nog niet klaar. Voordat we een werkend voorbeeld hebben, moeten we ApolloClient ook vertellen welke cachingstrategie moet worden gebruikt: InMemoryCache is de standaard en het is een goede waarmee we kunnen beginnen.

importeer {ApolloClient} van 'apollo-client'
importeer {HttpLink} uit 'apollo-link-http'
importeer {InMemoryCache} uit 'apollo-cache-inmemory'

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

Gebruik ApolloProvider

Nu moeten we de Apollo Client verbinden met onze componentenboom. We doen dit met behulp van ApolloProvider, door onze applicatiecomponent in het hoofd React-bestand te verpakken:

importeren Reageren van 'reageren'
ReactDOM importeren uit 'react-dom'
importeer {ApolloClient} van 'apollo-client'
importeer {HttpLink} uit 'apollo-link-http'
importeer {InMemoryCache} uit 'apollo-cache-inmemory'
importeer {ApolloProvider} van 'react-apollo'

app importeren uit './App'

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

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

Dit is genoeg om het standaard create-react-app-scherm weer te geven, met Apollo Client geïnitialiseerd:

De gql-sjabloontag

We zijn nu klaar om iets te doen met Apollo Client, en we gaan wat gegevens ophalen van de GitHub API en deze weergeven.

Hiervoor moeten we de gql-sjabloontag importeren:

import gql van 'graphql-tag'

Elke GraphQL-query wordt met deze sjabloontag gebouwd, zoals deze:

const query = gql`
  zoekopdracht {
    ...
  }
`

Voer een GraphQL-aanvraag uit

gql was het laatste item dat we nodig hadden in onze toolset.

We zijn nu klaar om iets te doen met Apollo Client, en we gaan wat gegevens ophalen van de GitHub API en deze weergeven.

Verkrijg een toegangstoken voor de API

Het eerste wat u moet doen, is een persoonlijk toegangstoken verkrijgen van GitHub.

GitHub maakt het gemakkelijk door een interface te bieden waaruit u de benodigde rechten kunt selecteren:

Voor deze voorbeeld-zelfstudie hebt u geen van deze machtigingen nodig. Ze zijn bedoeld voor toegang tot gegevens van privégebruikers, maar we zullen alleen de gegevens van openbare opslagplaatsen opvragen.

Het token dat je krijgt is een OAuth 2.0 Bearer token.

U kunt het eenvoudig testen door vanaf de opdrachtregel te lopen:

$ curl -H "Autorisatie: aan toonder *** _ YOUR_TOKEN_HERE _ ***" -X POST -d "\
 {\
   \ "query \": \ "query {viewer {login}} \" \
 } \
"https://api.github.com/graphql

wat u het resultaat zou moeten geven

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

of

{
  "message": "Slechte inloggegevens",
  "documentation_url": "https://developer.github.com/v4"
}

als er iets mis is gegaan.

Gebruik een Apollo Link om te verifiëren

Dus moeten we de autorisatiekop sturen samen met ons GraphQL-verzoek, net zoals in het bovenstaande curlverzoek.

We kunnen dit doen met Apollo Client door een Apollo Link-middleware te maken. Begin met het installeren van apollo-link-context:

npm installeer apollo-link-context

Met dit pakket kunnen we een authenticatiemechanisme toevoegen door de context van onze verzoeken in te stellen.

We kunnen het in deze code gebruiken door op deze manier naar de functie setContext te verwijzen:

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

  terug {
    headers: {
      ... headers,
      autorisatie: `Bearer $ {token}`
    }
  }
})

en zodra we deze nieuwe Apollo Link hebben, kunnen we deze samenstellen met de HttpLink die we al hadden door de concat () -methode op een link te gebruiken:

const link = authLink.concat (httpLink)

Hier is de volledige code voor het bestand src / index.js met de code die we nu hebben:

importeren Reageren van 'reageren'
ReactDOM importeren uit 'react-dom'
importeer {ApolloClient} van 'apollo-client'
importeer {HttpLink} uit 'apollo-link-http'
importeer {InMemoryCache} uit 'apollo-cache-inmemory'
importeer {ApolloProvider} van 'react-apollo'
import {setContext} uit 'apollo-link-context'
import gql van 'graphql-tag'

app importeren uit './App'

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

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

  terug {
    headers: {
      ... headers,
      autorisatie: `Bearer $ {token}`
    }
  }
})

const link = authLink.concat (httpLink)

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

ReactDOM.render (
  
    
  ,
  document.getElementById ( 'root')
)
WAARSCHUWING Houd er rekening mee dat deze code een voorbeeld is voor educatieve doeleinden. Het laat uw GitHub GraphQL API voor iedereen ter wereld zien in uw frontend-facing code. Productiecode moet dit token privé houden.

We kunnen nu het eerste GraphQL-verzoek onderaan dit bestand indienen en deze voorbeeldquery vraagt ​​naar de namen en de eigenaren van de 10 populairste repositories met meer dan 50.000 sterren:

const POPULAR_REPOSITORIES_LIST = gql`
{
  zoeken (zoekopdracht: "stars:> 50000", type: REPOSITORY, eerste: 10) {
    repositoryCount
    randen {
      node {
        ... op Repository {
          naam
          eigenaar {
            Log in
          }
          stargazers {
            totaal
          }
        }
      }
    }
  }
}
`

client.query ({query: POPULAR_REPOSITORIES_LIST}). vervolgens (console.log)

Het uitvoeren van deze code retourneert het resultaat van onze zoekopdracht in de browserconsole:

Geef een GraphQL-zoekresultaatset in een component weer

Wat we tot nu toe hebben gezien, is al cool. Wat nog cooler is, is het gebruik van de GraphQL-resultatenset om uw componenten te renderen.

We laten Apollo Client de last (of vreugde) hebben of het ophalen van de gegevens en het afhandelen van alle dingen op laag niveau. Hiermee kunnen we ons concentreren op het weergeven van de gegevens met behulp van de graphql component enhancer aangeboden door react-apollo:

importeren Reageren van 'reageren'
import {graphql} uit 'react-apollo'
import {gql} van 'apollo-boost'

const POPULAR_REPOSITORIES_LIST = gql`
{
  zoeken (zoekopdracht: "stars:> 50000", type: REPOSITORY, eerste: 10) {
    repositoryCount
    randen {
      node {
        ... op Repository {
          naam
          eigenaar {
            Log in
          }
          stargazers {
            totaal
          }
        }
      }
    }
  }
}
`

const App = graphql (POPULAR_REPOSITORIES_LIST) (props =>
  
        {props.data.loading? '': props.data.search.edges.map ((row, i) =>       
  •         {row.node.owner.login} / {row.node.name}: {''}                    {} Row.node.stargazers.totalCount                     )}    ) standaard app exporteren

Hier is het resultaat van onze zoekopdracht die is weergegeven in het onderdeel

Apollo Server

Een GraphQL-server heeft de taak om inkomende verzoeken op een eindpunt te accepteren, het verzoek te interpreteren en alle gegevens op te zoeken die nodig zijn om aan de behoeften van de klant te voldoen.

Er zijn heel veel verschillende GraphQL-serverimplementaties voor elke mogelijke taal.

Apollo Server is een GraphQL-serverimplementatie voor JavaScript, met name voor het Node.js-platform.

Het ondersteunt veel populaire Node.js-frameworks, waaronder:

  • uitdrukken
  • Hapi
  • Koa
  • Restify

De Apollo Server geeft ons in principe drie dingen:

  • Een manier om onze gegevens te beschrijven met een schema.
  • Het raamwerk voor resolvers, functies die we schrijven om de gegevens op te halen die nodig zijn om aan een verzoek te voldoen.
  • Het vergemakkelijkt de afhandeling van authenticatie voor onze API.

Om de basis van Apollo Server te leren, gaan we geen van de ondersteunde Node.js-frameworks gebruiken. In plaats daarvan zullen we iets gebruiken dat is gebouwd door het Apollo-team, iets wat echt geweldig is dat de basis van ons leren zal zijn: Launchpad.

Lanceerplatform

Launchpad is een project dat deel uitmaakt van de Apollo-paraplu van producten en het is een vrij verbazingwekkende tool waarmee we code in de cloud kunnen schrijven en online een Apollo Server kunnen maken, net zoals we een codefragment zouden uitvoeren op Codepen, JSFiddle of JSBin.

Behalve dat we in plaats van een visueel hulpmiddel te bouwen dat daar wordt geïsoleerd, en alleen bedoeld is als een etalage of als leermiddel, met Launchpad een GraphQL API maken. Het wordt publiek toegankelijk.

Elk project op Launchpad wordt pad genoemd en heeft zijn GraphQL-eindpunt-URL, zoals:

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

Nadat u een pad hebt gebouwd, geeft Launchpad u de mogelijkheid om de volledige code te downloaden van de Node.js-app waarop deze wordt uitgevoerd, en u hoeft alleen npm install en npm start uit te voeren om een ​​lokale kopie van uw Apollo GraphQL Server te hebben.

Om samen te vatten, het is een geweldig hulpmiddel om te leren, te delen en een prototype te maken.

De Apollo Server Hallo wereld

Telkens wanneer u een nieuw Launchpad-pad maakt, krijgt u de Hello, World! van Apollo Server. Laten we erin duiken.

Eerst importeert u de functie makeExecutableSchema uit graphql-tools.

import {makeExecutableSchema} uit 'graphql-tools'

Deze functie wordt gebruikt om een ​​GraphQLSchema-object te maken door het een schemadefinitie te geven (geschreven in de GraphQL-schemataal) en een set resolvers.

Een schemadefinitie is een letterlijke tekenreeks met de beschrijving van onze query en de typen die aan elk veld zijn gekoppeld:

const typeDefs = `
  type zoekopdracht {
    hallo: string
  }
`

Een resolver is een object dat velden in het schema toewijst aan resolverfuncties. Het kan gegevens opzoeken om op een vraag te reageren.

Hier is een eenvoudige resolver met de resolverfunctie voor het hallo-veld, die gewoon de Hello-wereld teruggeeft! draad:

const resolvers = {
  Zoekopdracht: {
    hallo: (root, args, context) => {
      terug 'Hallo wereld!'
    }
  }
}

Gegeven deze twee elementen, de schemadefinitie en de resolver, gebruiken we de makeExecutableSchema-functie die we eerder hebben geïmporteerd om een ​​GraphQLSchema-object te krijgen, dat we toewijzen aan het schema const.

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

Dit is alles wat u nodig hebt voor een eenvoudige alleen-lezen API. Launchpad zorgt voor de kleine details.

Hier is de volledige code voor het eenvoudige Hello World-voorbeeld:

import {makeExecutableSchema} uit 'graphql-tools'

const typeDefs = `
  type zoekopdracht {
    hallo: string
  }
`

const resolvers = {
  Zoekopdracht: {
    hallo: (root, args, context) => {
      terug 'Hallo wereld!'
    }
  }
}

export const schema = makeExecutableSchema ({
  typedefs,
  resolvers
})

Launchpad biedt een geweldige ingebouwde tool om de API te gebruiken:

En zoals ik eerder zei, de API is openbaar toegankelijk, dus je hoeft alleen maar in te loggen en je pad op te slaan.

Ik heb een pad gemaakt dat zijn eindpunt blootlegt op https://kqwwkp0pr7.lp.gql.zone/graphql, dus laten we het proberen met curl vanaf de opdrachtregel:

$ curl \
  -X POST \
  -H "Inhoudstype: applicatie / json" \
  --data '{"query": "{hallo}"}' \
  https://kqwwkp0pr7.lp.gql.zone/graphql

wat ons met succes het resultaat geeft dat we verwachten:

{
  "data": {
    "hallo": "Hallo wereld!"
  }
}

Voer de GraphQL Server lokaal uit

We hebben gezegd dat alles wat je op Launchpad maakt, kan worden gedownload, dus laten we doorgaan.

Het pakket bestaat uit twee bestanden. De eerste, schema.js is wat we hierboven hebben.

De tweede, server.js, was onzichtbaar in Launchpad en dat is wat de onderliggende Apollo Server-functionaliteit biedt, mogelijk gemaakt door Express, het populaire Node.js-framework.

Het is niet het eenvoudigste voorbeeld van een Apollo Server-installatie, dus om het uit te leggen, ga ik het vervangen door een eenvoudiger voorbeeld (maar voel je vrij om dat te bestuderen nadat je de basis hebt begrepen).

Uw eerste Apollo Server-code

Voer eerst npm install en npm start uit op de Launchpad-code die u hebt gedownload.

De knooppuntserver die we eerder hebben geïnitialiseerd, maakt meestal gebruik van nodemon om de server opnieuw op te starten wanneer de bestanden veranderen, dus wanneer u de code wijzigt, wordt de server opnieuw opgestart met de aangebrachte wijzigingen.

Voeg deze code toe in server.js:

const express = vereisen ('express')
const bodyParser = vereisen ('body-parser')
const {graphqlExpress} = vereisen ('apollo-server-express')
const {schema} = vereisen ('./ schema')

const server = express ()

server.use ('/ graphql', bodyParser.json (), graphqlExpress ({schema}))

server.listen (3000, () => {
  console.log ('GraphQL luistert op http: // localhost: 3000 / graphql')
})

Met slechts 11 regels is dit veel eenvoudiger dan de server die is ingesteld door Launchpad, omdat we alle dingen hebben verwijderd die die code flexibeler hebben gemaakt voor hun behoeften.

Codering dwingt je om moeilijke beslissingen te nemen: hoeveel flexibiliteit heb je nu nodig? Hoe belangrijk is het om schone, begrijpelijke code te hebben die je vanaf nu zes maanden kunt ophalen en gemakkelijk kunt aanpassen of doorgeven aan andere ontwikkelaars en teamleden zodat ze productief kunnen zijn in zo weinig tijd als nodig?

Dit is wat de code doet:

We importeren eerst enkele bibliotheken die we gaan gebruiken.

  • express waarmee de onderliggende netwerkfunctionaliteit het eindpunt kan blootleggen
  • bodyParser is de middleware voor het parseren van knooppunten
  • graphqlExpress is het Apollo Server-object voor Express
const express = vereisen ('express')
const bodyParser = vereisen ('body-parser')
const {graphqlExpress} = vereisen ('apollo-server-express')

Vervolgens importeren we het GraphQLSchema-object dat we in het bestand schema.js hierboven hebben gemaakt als Schema:

const {schema} = vereisen ('./ schema')

Hier is een standaard Express-set en we initialiseren zojuist een server op poort 3000

const server = express ()

Nu zijn we klaar om Apollo Server te initialiseren:

graphqlExpress ({schema})

en we geven dat door als een callback naar ons eindpunt voor HTTP JSON-aanvragen:

server.use ('/ graphql', bodyParser.json (), graphqlExpress ({schema}))

Het enige dat we nu nog moeten doen is Express starten:

server.listen (3000, () => {
  console.log ('GraphQL luistert op http: // localhost: 3000 / graphql')
})

Voeg een GraphiQL-eindpunt toe

Als u GraphiQL gebruikt, kunt u eenvoudig een / graphiql-eindpunt toevoegen om te consumeren met de GraphiQL interactieve IDE in de browser:

server.use ('/ graphiql', graphiqlExpress ({
  eindpuntURL: '/ graphql',
  zoekopdracht: ``
}))

We moeten nu alleen de Express-server opstarten:

server.listen (PORT, () => {
  console.log ('GraphQL luistert op http: // localhost: 3000 / graphql')
  console.log ('GraphiQL luistert op http: // localhost: 3000 / graphiql')
})

Je kunt het testen door opnieuw krullen te gebruiken:

$ curl \
  -X POST \
  -H "Inhoudstype: applicatie / json" \
  --data '{"query": "{hallo}"}' \
  http: // localhost: 3000 / graphql

Dit geeft u hetzelfde resultaat als hierboven, waar u de Launchpad-servers hebt genoemd:

{
  "data": {
    "hallo": "Hallo wereld!"
  }
}
Wilt u JavaScript leren? Ontvang mijn gratis ebook op jshandbook.com