A complete introduction to the GraphQL toolkit Apollo

Apollo is a set of tools for creating GraphQL servers and using GraphQL API. Let's learn more about Apollo client and Apollo server.

The Apollo Logo

Introduction to Apollo

in the past few yearsGraphQLIt is widely welcomed as an alternative to building APIs on REST.

GraphQL is a good way to let the client decide what data to transmit over the network, rather than let the server send a fixed set of data.

In addition, it also allows you to specify nested resources, which reduces the trouble of sometimes going back and forth when dealing with REST APIs.

Apollo is a GraphQL-based team and community, and provides different tools to help you build projects.

The tools provided by Apollo are mainly 3:client,server,engine.

Apollo customersHelp you use GraphQL API and support the most popular front-end web technologies, including React,Vue, Angular, Ember, Meteor, etc., as well as native development on iOS and Android.

Apollo serverIt is the server part of GraphQL, which connects with your backend and sends the response back to the client request.

Apollo EngineIt is a hosting infrastructure (SAAS) that acts as an intermediary between the client and the server, providing caching, performance reporting, load measurement, error tracking, architectural field usage statistics, historical statistics, and many other functions. It currently releases up to one million requests per month for free, and is the only part of Apollo that is not open source and free, and it provides funding for the open source part of the project.

It is worth noting that these three tools are not linked together in any way. For example, you can only use Apollo Client to interface with third-party APIs, or you can use Apollo Server to provide APIs without a client at all.

AllCompatible with GraphQL standard specifications, So there is no proprietary or incompatible technology in Apollo.

But it is very convenient to put all these tools under one roof. This is a complete package that can meet all your GraphQL-related needs.

Apollo strives to be easy to use and easy to contribute.

Apollo focuses onKeep it simple. This is the key to the success of the technology to be popularized, because certain technologies or frameworks or libraries may be too large for 99% of small and medium-sized companies, and are only suitable for large companies with very complex needs.

Apollo customers

Apollo customersIt is the leading JavaScript client of GraphQL. It is community-driven and aims to allow you to build UI components that interact with GraphQL data to display data or perform mutations when certain operations occur.

You do not need to change everything in the application to use Apollo Client. You can start with a small layer, one request, and then expand from there.

Most importantly, the construction of Apollo Client is simple, small and flexible from the beginning.

In this article, I will detail the process of using Apollo Client in React applications.

I will useGitHub GraphQL APIAs a server.

Start a React application

I usecreate-react-appSetting up the React application is very convenient, and just add what we need:

npx create-react-app myapp

npxIs the latest commandnpmversion. If you do not have this command, please update npm.

And use npm to start the application local server:

npm start

This will launch an applicationlocalhost:3000.

Open nowsrc/index.js:

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import registerServiceWorker from './registerServiceWorker'

ReactDOM.render(<App />, document.getElementById(‘root’)) registerServiceWorker()

And delete all of them.

Start using Apollo Boost

Apollo Boost is the easiest way to start using Apollo Client on a new project. In addition to installation, we will also installreact-apollowithgraphql.

In the console, run

npm install apollo-boost react-apollo graphql

Create an ApolloClient object

You first import ApolloClient fromapollo-clientinindex.js:

import { ApolloClient } from 'apollo-client'

const client = new ApolloClient()

By default, Apollo Client uses/graphqlThe endpoint on the current host, so let's useApollo LinkSpecify the connection details with the GraphQL server by setting the GraphQL endpoint URI.

Apollo link byHttpLinkObjects we import fromapollo-link-http.

Apollo Link provides us with a way to describe how we get the results of GraphQL operations and how to process the responses.

In short, you will create multiple Apollo Link instances, which will all act on GraphQL requests one after the other to provide the desired final result. Some links allow you to choose to retry the request (if unsuccessful), batch processing, etc.

We add the Apollo link to our Apollo Client instance to use the GitHub GraphQL endpoint URIhttps://api.github.com/graphql

import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'

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

Cache

We are not done yet. Before we have a viable example, we must also tellApolloClientWhichCaching strategyuse:InMemoryCacheIt is the default setting, which is a good starting point.

import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'

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

useApolloProvider

Now, we need to connect the Apollo client to our component tree. We useApolloProviderBy wrapping our application components in the main React file:

import React from 'react'
import ReactDOM from 'react-dom'
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloProvider } from 'react-apollo'

import App from ‘./App’

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

ReactDOM.render( <ApolloProvider client={client}> <App /> </ApolloProvider>, document.getElementById(‘root’) )

This is enough to render the default valuecreate-react-appScreen, Apollo Client is initialized:

create-react-app running Apollo Client

ThisgqlTemplate tag

Now, we are ready to use Apollo Client to do some things, and we will get some data from the GitHub API and render it.

For this, we need to importgqlBeginning of template tagindex.js:

import gql from 'graphql-tag'

Any GraphQL query will be constructed using this template tag as shown below:

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

Execute GraphQL request

entergqlIt is the last item needed in our tool set.

Now, we are ready to use Apollo Client to do some things, and we will get some data from the GitHub API and render it.

Get API access token

The first thing to do isGet personal access tokenFrom GitHub.

GitHub simplifies operations by providing an interface from which you can choose any permissions you may need:

GitHub interface to create a new personal access token

In this example tutorial, you don't need any of these permissions, they are only used to access private user data, but we only query public repository data.

However, you still need the token.

The token you get isOAuth 2.0 bearer token.

You can easily test it by running from the command line:

$ curl -H "Authorization: bearer ***_YOUR_TOKEN_HERE_***" -X POST -d " \
 { \
   \"query\": \"query { viewer { login }}\" \
 } \
" https://api.github.com/graphql

(instead***_YOUR_TOKEN_HERE_***With actual token)

This should give you the result

{"data":{"viewer":{"login":"***_YOUR_LOGIN_NAME_***"}}}

or

{
  "message": "Bad credentials",
  "documentation_url": "https://developer.github.com/v4"
}

If something goes wrong, for example, you forgot to insert the token.

Now we need to sendAuthorizationHeaders and our GraphQL request, just like we are incurlThe above requirements.

How do we use Apollo Client by creating Apollo Link middleware. Start with installationapollo-link-context:

npm install apollo-link-context

This package allows us to add an authentication mechanism by setting the context of the request.

We can use it in this code by referencing the following codesetContextRun it this way:

import { setContext } from 'apollo-link-context'

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

return { headers: { …headers, authorization: Bearer </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">token</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> } } })

Once we have this new Apollo Link, we canwriteversusHttpLinkWe already have it, by usingconcat()Method on the link:

const link = authLink.concat(httpLink)

This is the complete codesrc/index.jsArchive with the code we have now:

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

import App from ‘./App’

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

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

return { headers: { …headers, authorization: Bearer </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">token</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> } } })

const link = authLink.concat(httpLink)

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

ReactDOM.render( <ApolloProvider client={client}> <App /> </ApolloProvider>, document.getElementById(‘root’) )

Warning ⚠️🚧 remember that this code isexampleFor educational purposes, it exposes the GitHub GraphQL API token to the world for viewing in front-end-facing code. The production code needs to keep this token private on the backend.

Now, we can make the first GraphQL request at the bottom of the file. This example query will ask for the names and owners of the 10 most popular repositories (over 50,000 stars):

const POPULAR_REPOSITORIES_LIST = gql`
{
  search(query: "stars:>50000", type: REPOSITORY, first: 10) {
    repositoryCount
    edges {
      node {
        ... on Repository {
          name
          owner {
            login
          }
          stargazers {
            totalCount
          }
        }
      }
    }
  }
}
`

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

Successfully running this code will return the query result in the browser console:

console log of executed query

Render the GraphQL query result set in the component

What we have seen so far is pretty cool. What's even cooler is to use graphql result sets to present your components.

We make Apollo Client burden (or happy) or get data and handle all low-level content, and we can focus on displaying data by usinggraphqlComponent enhancer provided byreact-apollo.

Add this toApp.jsfile:

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

const POPULAR_REPOSITORIES_LIST = gql </span><span style="color:#e6db74">{ </span><span style="color:#e6db74"> search(query: "stars:&gt;50000", type: REPOSITORY, first: 10) { </span><span style="color:#e6db74"> repositoryCount </span><span style="color:#e6db74"> edges { </span><span style="color:#e6db74"> node { </span><span style="color:#e6db74"> ... on Repository { </span><span style="color:#e6db74"> name </span><span style="color:#e6db74"> owner { </span><span style="color:#e6db74"> login </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> stargazers { </span><span style="color:#e6db74"> totalCount </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74">} </span><span style="color:#e6db74">

const App = graphql(POPULAR_REPOSITORIES_LIST)(props => <ul> {props.data.loading ? ‘’ : props.data.search.edges.map((row, i) => <li key={row.node.owner.login + ‘-’ + row.node.name}> {row.node.owner.login} / {row.node.name}: {’ '} <strong> {row.node.stargazers.totalCount} </strong> </li> )} </ul> )

export default App

This is the result of the query rendered in the component rendered

The result of our query rendered in the component


Apollo server

The job of the GraphQL server is to accept incoming requests on the endpoint, interpret the request and find any data needed to meet the client's needs.

There are many different GraphQL server implementations for each possible language.

Apollo Server is a GraphQL server implementation for JavaScript, especially forNode.jsplatform.

It supports many popular Node.js frameworks, including:

Apollo Server basically gives us 3 things:

  • Provides us with a way to describe our dataSchema.
  • Provide a framework forParser, This is the function we wrote to extract the data needed to satisfy the request.
  • Easy to handleverificationUsed in our API.

First, create a folder namedappserver, Enter it and runnpm init --yesInitialize onepackage.jsonfile.

Then runnpm install apollo-server graphql.

Apollo Playground

If you prefer online playgrounds, then I suggest you choose 2 amazing Apollo playgrounds.

The first one is hosted onglitch,the secondCodeSandbox.

To remix/fork these entry projects to create your own Apollo Server.

Apollo server Hello World

Createindex.jsfile.

First you importApolloServerwithgqlFromapollo-server:

const { ApolloServer, gql } = require('apollo-server');

We usegqllabel. The schema definition is a template literal string that contains the description of the query and the type associated with each field:

const typeDefs = gql`
  type Query {
    hello: String
  }
`

A kindParserIt is the object that maps the fields in the schema to the parser function, and the object can find data in response to queries.

This is a simple parser, which contains forhelloField, the field returnsHello world!String:

const resolvers = {
  Query: {
    hello: (root, args, context) => {
      return 'Hello world!'
    }
  }
}

Given these two elements, the schema definition and the parser, we initialize a new ApolloServer object:

const server = new ApolloServer({ typeDefs, resolvers })

Then, we call the listen() method on the server object and listen for the promise to be resolved, which indicates that the server is ready:

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`)
})

This is the complete code of the simple Hello World example:

const { ApolloServer, gql } = require('apollo-server');

// Construct a schema, using GraphQL schema language const typeDefs = gql </span><span style="color:#e6db74"> type Query { </span><span style="color:#e6db74"> hello: String </span><span style="color:#e6db74"> } </span><span style="color:#e6db74">

// Provide resolver functions for your schema fields const resolvers = { Query: { hello: (root, args, context) => { return ‘Hello world!’ } } }

const server = new ApolloServer({ typeDefs, resolvers })

server.listen().then(({ url }) => { console.log(🚀 Server ready at </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">url</span><span style="color:#e6db74">}</span><span style="color:#e6db74">) })

Run nownode index.jsAnd run from another console window:

$ curl \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{ "query": "{ hello }" }' \
  http://localhost:4000/graphql

This should return your data:

{
  "data": {
    "hello": "Hello world!"
  }
}

You can use this simple App.js file example to connect your client to this interface. You can insert this example from the GitHub API example above:

import React from 'react'
import { gql } from 'apollo-boost'
import { Query } from 'react-apollo'

const App = () => ( <Query query={gql</span><span style="color:#e6db74"> { </span><span style="color:#e6db74"> hello </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } > {({ loading, error, data }) => { if (loading) return <p>Loading</p> if (error) return <p>Error :(</p>

  <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">data</span>.<span style="color:#a6e22e">hello</span>
}}

</Query> )

export default App

You must changehttpLinkuri inindex.jsArchive to:

const httpLink = createHttpLink({ uri: 'http://localhost:4000/graphql' })

More graphql tutorials: