Table of Contents
URL: https://www.progressiverobot.com/react-graphql-apollo-boost/
The Apollo GraphQL client is a very popular way to interface with a GraphQL API on the client-side. In this post we'll go over how to setup Apollo in a React app using <^>Apollo Boost<^> and <^>React Apollo 2.1<^>.
What are these two for, you ask?
- <^>Apollo Boost<^>: Setting up Apollo on the client used to require quite a lot of boilerplate code, and Apollo Boost fixes that. It's a bundled combination of <^>apollo-client<^>, <^>apollo-cache-inmemory<^>, <^>apollo-link-error<^>, <^>apollo-link-http<^> and <^>apollo-link-state<^> that allows for a much easier setup.
- <^>React Apollo<^>: A React-specific integration for Apollo. It provides us with a lot of goodies like the
QueryandMutationcomponents.
This tutorial assumes the use of React Apollo 2.1+
Installation
Let's first initialize a React project using npx and Create React App:
$ npx create-react-app hello-graphql
You can then cd into the project and start a local dev server:
$ cd hello-graphql && yarn start
We'll also need a few extra packages in our project, namely <^>graphql<^>, <^>graphql-tag<^>, <^>apollo-boost<^> and <^>react-apollo<^>. Add them using npm or Yarn:
$ yarn add graphql graphql-tag apollo-boost react-apollo
# or, using npm:
$ npm i graphql graphql-tag apollo-boost react-apollo
With our project in place and packages added, we can now setup the Apollo client.
Setup
The client setup couldn't be easier. We'll initiate a client and give it the URI to our GraphQL server endpoint and then use the <^>ApolloProvider<^> component to to make the client available in our app's components.
For this example our endpoint will point to an Apollo Launchpad instance with data about Star Wars:
[label index.js]
import React from 'react';
import ReactDOM from 'react-dom';
import { ApolloProvider } from 'react-apollo';
import { ApolloClient, HttpLink, InMemoryCache } from 'apollo-boost';
import './index.css';
import App from './App';
const client = new ApolloClient({
link: new HttpLink({ uri: 'https://mpjk0plp9.lp.gql.zone/graphql' }),
cache: new InMemoryCache()
});
const AppWithProvider = () => (
<ApolloProvider client={client}>
<App />
</ApolloProvider>
);
ReactDOM.render(<AppWithProvider />, document.getElementById('root'));
A few things to note:
- We initialize the client with an <^>HttpLink<^> that points to our GraphQL endpoint and then also specify Apollo's InMemoryCache as the caching utility.
- We use the
ApolloProvidercomponent, pass it our client as prop and then wrap it around ourAppcomponent.
Query Component Example
Now that everything's in place, we can start running queries against the GraphQL endpoint. For this, we'll use React Apollo's Query component, which makes use of the render prop pattern to give us the data back from the query.
Here's an example where we query for a Star Wars' episode hero and his/her friends:
[label App.js]
import React from 'react';
import PropTypes from 'prop-types';
import { Query } from 'react-apollo';
import gql from 'graphql-tag';
const QUERY = gql`
query HeroFriends($episode: Episode!) {
hero(episode: $episode) {
name
friends {
name
}
}
}
`;
const HeroAndFriends = ({ episode }) => (
<Query query={QUERY} variables={{ episode }}>
{({ data, error, loading }) => {
if (error) return '💩 Oops!';
if (loading) return 'Patience young grasshopper...';
return (
<React.Fragment>
<h1>Hero: {data.hero.name}</h1>
<h2>His/her friends:</h2>
<ul>
{data.hero.friends.map(friend => (
<li key={friend.name}>{friend.name}</li>
))}
</ul>
</React.Fragment>
);
}}
</Query>
);
HeroAndFriends.propTypes = { episode: PropTypes.string };
HeroAndFriends.defaultProps = { episode: 'NEWHOPE' };
const App = () => <HeroAndFriends episode="EMPIRE" />;
export default App;
And let's breakdown the important things happening here:
- React Apollo's
Querycomponent takes a required <^>query<^> prop with a GraphQL query that has been parsed using graphql-tag's <^>gql<^>.Queryalso takes a required <^>children<^> prop that should be a function. Here we also passed-in a <^>variable<^> prop to provide a variable value to our query.
Querycan also take a number of optional props like <^>pollInterval<^>, <^>fetchPolicy<^>, <^>errorPolicy<^> and <^>delay<^>, among others.
- The function passed to the children prop receives an object with a handful of useful properties. Here we're making use of <^>data<^>, <^>error<^> and <^>loading<^>, but other properties like <^>networkStatus<^>, <^>refetch<^> and <^>fetchMore<^> are also available.
- The <^>data<^> property holds the data received back from the query, the <^>error<^> property holds an error object, if any, and the loading property will be true while the query is in-flight.
⚛️ There you have it!
An easy way to get started with React and GraphQL and start running queries. In a future post we'll also explore the Mutation component to also run GraphQL mutations. You can also dive a little bit deeper by having a look at the official docs.