Author avatar

Benney Au

How to Set Up GraphQL in a React App

Benney Au

  • Sep 23, 2020
  • 7 Min read
  • 24,302 Views
  • Sep 23, 2020
  • 7 Min read
  • 24,302 Views
Web Development
Client-side Frameworks
React
Front End Web Development

Introduction

GraphQL is a query language for querying exactly what you want from many resources in a single request. It is intended for clients such as web apps to be more performant and to make it easier to work with backend data.

This guide will demonstrate how to integrate GraphQL into your React app using Apollo Client. You will use configure Apollo Client and then the useQuery to retrieve data from graphQL and REST endpoints. This guide assumes a basic understanding of React Hooks.

Start a New React Project

Start by creating a new React project by running the following commands:

1npx create-react-app my-graphql-react-project
2cd my-graphql-react-project
3yarn add @apollo/client graphql

These commands set up a new React project and install @apollo/client, which is a stable and mature graphQL library. Apollo helps with state management and in-memory caching in your app. This allows you to achieve more with less code compared to a React Redux project.

Set Up Apollo Client

To start using ApolloClient to query a graphQL endpoint in your React app, you must set up a client and make it available to relevant components.

Create the file src/ApolloClient/client.js and insert the following code.

1import { ApolloClient, ApolloLink, InMemoryCache } from "@apollo/client";
2import { RestLink } from "apollo-link-rest";
3
4const httpLink = new HttpLink({
5  uri: "https://48p1r2roz4.sse.codesandbox.io",
6});
7
8export const client = new ApolloClient({
9  cache: new InMemoryCache(),
10  link: ApolloLink.from([httpLink]),
11});
javascript

Two pieces of configuration are required:

  1. link allows you to customize the flow of data from your graphQL queries and mutations to your backend and in-app state management. This can include: adding custom headers and routing to REST endpoints and graphQL endpoints.
  2. cache allows you to prevent unnecessary networks requests when you already have the data.

The code sample above connects to a simple sandbox graphQL endpoint that provides currency exchange rate data.

Make ApolloClient Available to the REST of Your App

With the client configuration, you can use React's Context API so that your child components can access your configuration and make queries and mutations. To do this, update your src/App.js to the following:

1import React from "react";
2import "./App.css";
3import { client } from "./ApolloClient/client";
4import { ApolloProvider } from '@apollo/client';
5import ExchangeRatesPage from './ExchangeRatesPage';
6
7function App() {
8  return (
9    <ApolloProvider client={client}>
10      <div className="App">
11        <ExchangeRatesPage />
12      </div>
13    </ApolloProvider>
14  );
15}
16
17export default App;
javascript

You have imported the client you created earlier and wrapped everything with the ApolloProvider component. These changes are necessary so that the ExchangeRatesPage component that you will create in the next section knows how to fetch data.

Make a GraphQL Query from a Component

With the ApolloClient in context, child components of App.js can use the useQuery and useLazyQuery hooks to query data.

This section describes how to use the useQuery hook. Create the file src/ExchangeRatePage.js

1import React from "react";
2import { useQuery, gql } from "@apollo/client";
3
4const EXCHANGE_RATES = gql`
5  query GetExchangeRates {
6    rates(currency: "AUD") {
7      currency
8      rate
9    }
10  }
11`;
12
13function ExchangeRatePage() {
14  const { data, loading, error } = useQuery(EXCHANGE_RATES);
15
16  if (loading) {
17    return <div>loading</div>;
18  }
19
20  if (error) {
21    return <div>{error}</div>;
22  }
23
24  return data.rates.map(({ currency, rate }) => (
25    <div key={currency}>
26      <p>
27        {currency}: {rate}
28      </p>
29    </div>
30  ));
31}
32
33export default ExchangeRatePage;
javascript

When this component is loaded, it immediately makes the query to the server, and the loading property is set to true. Once the data is returned, your component is immediately rerendered and the data property is populated. You should notice that there is much less boilerplate to get started querying data. Loading and error states properties are handled for you. If you would like more control over loading, you can use the useLazyQuery hook and call the return function when you want to trigger the fetch operation.

Use GraphQL to Query REST Resources

If you have a set of REST endpoints, you can still use Apollo and GraphQL to query this data. To do this, you need to install apollo-rest-link. Run the following commands to install the required packages.

1yarn add graphql-anywhere apollo-link-rest

Then update your src/ApolloClient/client.js file to the following:

1import { ApolloClient, ApolloLink, InMemoryCache } from "@apollo/client";
2import { RestLink } from "apollo-link-rest";
3import { HttpLink } from "apollo-link-http";
4
5const restLink = new RestLink({
6  endpoints: {
7    openExchangeRate: "https://open.exchangerate-api.com/v6/",
8  },
9});
10
11const httpLink = new HttpLink({
12  uri: "https://48p1r2roz4.sse.codesandbox.io",
13});
14
15export const client = new ApolloClient({
16  cache: new InMemoryCache(),
17  link: ApolloLink.from([restLink, httpLink]),
18});
javascript

You've now configured two ApolloLinks:

  • HttpLink handles requests to your graphQL endpoint
  • RestLink handles requests to one or more REST endpoints

To activate your RestLink, you can use the @rest graphQL directive. Update your EXCHANAGE_RATES query to the following:

1onst EXCHANGE_RATES = gql`
2  query GetExchangeRates {
3    rates(currency: "AUD") {
4      currency
5      rate
6    }
7    openExchangeRates @rest(type: "openExchangeRates", path: "/latest", endpoint: "openExchangeRate") {
8      rates
9    }
10  }
11`;
javascript

Apollo Client will make a request to your REST endpoint with your graphQL endpoint. The URI to your rest endpoint will be constructed by combining the path specified in the @rest directive and endpoint configured in the client.js. In this case, the URI would be resolved to https://open.exchangerate-api.com/v6/latest. The results of your REST request will be appended to the data property returned from the useQuery hook. If your request is successful, the structure of the data property will look like this:

1{
2  "rates": [ { "currency": "AED", "rate": "2.67777" } ],
3  "openExchangeRate": {
4    "rates": { "ARS": 75.17 }
5  }
6}
json

At the root, the rates from the graphQL endpoint are unioned with the openExchangeRate property from the REST endpoint.

From a client perspective, this is convenient since you can benefit from Apollo's caching and state management without completely rewriting your backend to GraphQL.

Conclusion

Interacting with remote data is a large component of modern web apps. Using Apollo and GraphQL, querying data from REST and GraphQL endpoints becomes much easier. As a next step, you may want to explore other Apollo features such as mutations and subscription.