GraphQL for React Developers With Apollo
By: Moshood Abidemi
Tags: React Hook, React, Apollo Client, GraphQL

Photo by AltumCode on Unsplash

What’s GraphQL?

GraphQL is a query language for APIs that enables declarative data-fetching. GraphQL queries always return predictable results. GraphQL queries adapt to a very strict and predefined structure for query results. Unlike REST APIs which may return some unneeded data, with GraphQL, we can specify the exact data we need.

I like to think of GraphQL as just a spec for a query language for client-server interactions. GraphQL was designed by Facebook in 2012 and the GraphQL spec was open-sourced in 2015.

Why GraphQL?

The main advantage of GraphQL over the REST architecture is that it solves the problem of over-fetching and under-fetching of data. In a scenario where we have to fetch a user data in REST, we’ll use a GET request with an endpoint of ‘/user/id’ but we only need the user’s name on the frontend. The endpoint has to be modified to return only the user’s name. But what if in addition to the user’s name, we need the user’s age in another part of the frontend, then the endpoint will be modified again to includes the user’s age. This lead to over-fetching on the first request where only name is needed. With GraphQL, we can define the exact data we need without over-fetching.

Also, imagine a scenario where we need to fetch the transaction details of a user, we’ll probably need to make another endpoint like ‘/user/:id/transaction’ which leads to multiple request to the server since we have to make a request to ‘/user/:id’ first. With GraphQL, we can combine this into a single request.

Drawbacks of GraphQL

All requests returns a status of 200 It uses a single endpoint for all requests Caching can be more difficult to implement than in REST

GraphQL Basics

GraphiQL

GraphiQL is the GraphQL integrated development environment (IDE). GraphiQL provides interface to view the graphql schemas which includes the queries and mutations.

There’s also an online GraphiQL interface which we’ll be using for this article. We’ll be using this graphql API endpoint https://countries.trevorblades.com/ to test out queries and mutations.

Queries

As the name suggests, queries are used to fetch data from a GraphQL server. Since GraphQL queries are declarative, we can define the exact data that should be returned. A basic GraphQL looks like this

After running the graphQL query above from a graphql server, we get this response

Mutations

Mutations are special types of queries that are used to create, update or delete data. It should be noted that it is required to return data from a Graphql mutation

Fragments

Fragments are reusable piece of the structure of a data. Fragments can be used to represent the structure of a data that needs to be fetched.

Using GraphQL in React

Apollo Client

The ApolloClient is a state management library used to create, update and cache the results of graphql queries and mutations. The ApolloClient makes it super easy to work with GraphQL in React. To use the ApolloClient in a React project, we need to install the @apollo/client package

This can be installed by running npm install @apollo/client or yarn add @apollo/client . We also need to install the graphql package by running npm install graphql or yarn add graphql

Initialize the ApolloClient

The ApolloClient needs to be initialized before using it. To do these we need to pass some options into the instance.

Below is a brief explanation about some of the options

uri: the url of the graphql server

cache: the cache that Apollo uses to store the results of query locally. This is required

link: an Apollo link instance can be provided in place of the uri. This is required if uri is not provided. It takes precedence if both are provided

name: a custom name for the client instance

version: a custom version for the instance of the Apolloclient

ssrMode: should be set to true if server-side rendering should be enabled

ssrForceDelay: time interval before Client force-fetches queries after a server-side render.

ApolloProvider

After initializing the server, we need a way to connect it to the react app, this can be done using the ApolloProvider. The ApolloProvider is a react component that connects the ApolloClient to the react app. We need to wrap the whole app in the ApolloProvider to get access to the ApolloClient throughout the app.

We need to pass instance of the client as props to the ApolloProvider

Using the ApolloClient

Apollo provides some sets of hooks and functions for creating graphql queries and mutations. Below are some of them

gql

gql is a function provided by @apollo/client package for parsing literal strings into graphql queries . An example query with gql looks like this.

useQuery

useQuery is the hook for executing graphql queries in Apollo, it accepts two arguments, the first is the query itself and the second is an optional object for additional configurations. Some of the additional options that are part of the second parameter to useQuery are discussed briefly below:

variables: an object containing the variables that should be passed to the query. Each key in the object corresponds to a variable name, and that key’s value corresponds to the variable value.

OnCompleted: A callback function that’s called when your query successfully completes

onError: A callback function that’s called when the query encounters one or more errors

client: The instance of ApolloClient to use to execute the query.

The useQuery hooks return an object which contains the data, loading and error returned from the query. It also returns some additional properties which includes

previousData: returns result of the most recent executed query

client: the ApolloClient instance used to execute the query

fetchMore: a function for fetching more data from the query

refetch: a function to refetch the query

updateQuery: a function to update the query

useMutation

The useMutation hooks allows you to execute graphql mutations. The first parameter is the gql template literal for the mutation and the second parameter are additional configuration options. The options are mostly similar to that of useQuery . The useMutation hook returns an array, the first element in the array is a function that can be called to execute the mutation, the second value in the array is an object that contains the data, loading, error state and some additional options similar to the useQuery hook.

Updating the cache

Since graphql caches query result, when a new query is executed, the apollo client automatically update the cache for that query as long as an id is returned from the query but there are some instances where we’ll need to manually update the query, the @apollo/client package provides some functions for manually updating the apollo cache. These functions include

writeFragment: used to manually update the value of a cached fragment. There is also a readFragment option to read the value of a cached fragment writeQuery: used to manually update the value of a cached query result. There is also a readQuery function to read the value of a cached query result. Any change made here is not pushed to the server.

Optimistic Response