Sofware Development
Apollo client and React
August 18, 2020
by
tintef
> “🚀 A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server” — [Apollo Client github repository](https://github.com/apollographql/apollo-client)## Why do we need a GraphQL client?As GraphQL backends expose their API over a single HTTP endpoint, we could just use fetch to interact with it. The problem is this doesn’t scale well because we would need to reimplement backend agnostic features on every project, such as caching data, updating the local cache after a mutation, UI framework integration, and more!A GraphQL client should have those kinds of functionalities so that you don’t have to reimplement these behaviors yourself. Instead, you can completely focus on your application domain and on implementing the specific requirements of your app.As we should expect, there is a multitude of GraphQL clients to choose from, in this article we’ll go over [Apollo Client](https://www.apollographql.com/docs/react/).## Why Apollo Client?> “Apollo Client is a complete state management library for JavaScript apps. Simply write a GraphQL query, and Apollo Client will take care of requesting and caching your data, as well as updating your UI.” — [Apollo Client docs](https://www.apollographql.com/docs/react/)Apollo provides a lightweight and flexible approach that works in any environment. Many tasks such as keeping the local cache consistent can also be achieved with Apollo Client, but require more manual work and bookkeeping.Since Apollo Client is framework agnostic, it’s a great option to learn and use in your applications. Everything you learn can be used on React, Vue, and even on native apps!In this article, we’ll see how to use Apollo Client with React.## SetupFirst, we need to add the required dependencies to use Apollo Client on a React application, using either npm or yarn.Dependencies required to use Apollo Client on a React app:```shnpm install --save react-apollo graphql graphql-tag apollo-cache-inmemory apollo-client apollo-link-http```Once we’ve successfully installed the dependencies, we have to set up the Apollo Client. To do so, we only need to let it know our GraphQL endpoint. Note that we are also using an in-memory cache, we’ll cover this later.Basic Apollo Client configuration:```jsimport ApolloClient from "apollo-client";import { HttpLink } from "apollo-link-http";import { InMemoryCache } from "apollo-cache-inmemory";const cache = new InMemoryCache();const link = new HttpLink({ uri: process.env.GRAPHQL_API_URL });export const apolloClient = new ApolloClient({ name: "our-awesome-client", link, cache,});```Now that we’ve created our client, we need to wrap our application in the `ApolloProvider` tag, so that our app has access to our newly created client.```jsximport React from "react";import ReactDOM from "react-dom";import { ApolloProvider } from "react-apollo";import App from "./containers/App";import { apolloClient } from "./graphQL/client";ReactDOM.render( , document.getElementById("mount"));```As you should know by now (if you don’t, check out this [awesome article](./introduction-to-graphql)), in GraphQL we use `Queries` to retrieve data and `Mutations` to mutate data.In our React app, there are two ways to do either of them, by using components or hooks. We’ll cover the latter as they are much cleaner and more pleasant to work with.## QueriesLet’s say we want to get the `id` and `name` of all the _Users_ on our imaginary GraphQL backend. This is easily done by writing the following query.Now, we can use this query to actually fetch some users by using the `useQuery` hook. In order to run a query, we need to call `useQuery` and pass a GraphQL query string to it. This hook returns a result object that contains the following properties:```graphqlconst FETCH_USERS = gql`{ users { id name }}`;```- `loading`: whether the request is in flight or not.- `data`: the result of your GraphQL query (defaults to `undefined`).- `error`: a runtime error with `graphQLErrors` and `networkError` properties.- …and [more](https://www.apollographql.com/docs/react/data/queries/).Usage example of `useQuery`:```jsximport { useQuery } from "@apollo/react-hooks";import FETCH_USERS from "../graphQL/queries/fetchUsers";const Component = () => { const { loading, data, error } = useQuery(FETCH_USERS); if (loading) return "Loading..."; if (error) return "Oops :("; return (
- {name}
);};```## MutationsAs an example, we may want to create a `Post` with a `title` and a `body`. To do this, we must write a mutation:```graphqlmutation CreatePost($input: CreatePostInput!) { createPost(input: $input) { post { title body id createdAt } }}```Here, `CreatPostInput` is a GraphQL type defined in our backend, that has `title` and `body` fields.To use this mutation we can use the `useMutation` hook. This hook returns an array where this first item is the mutation itself and the second item is pretty similar to the one returned by `useQuery`.Usage example of useMutation:```jsximport { useMutation } from "@apollo/react-hooks";import CREATE_POST from "../graphQL/queries/createPost";const Component = () => { const [createPost, { loading }] = useMutation(CREATE_POST); return ( { ev.preventDefault(); const { title, body } = ev.target.elements; createPost({ variables: { title, body } }); }} > Title Body <button type="submit">{loading ? "Loading..." : "Submit"}</button></form> );};```## Apollo Cache> “Apollo Client stores the results of its GraphQL queries in a normalized, in-memory cache. This enables your client to respond to future queries for the same data without sending unnecessary network requests.” — [Apollo Client docs](https://www.apollographql.com/docs/react/caching/cache-configuration/)What does this mean? It means that we can use this in-memory cache as our global state, no need to use Redux or Context!Apollo exposes a handful of functions to read and write the cache. To keep this post short we won’t cover it, but you can read about it in [Apollo’s documentation](https://www.apollographql.com/docs/react/caching/cache-interaction/).<hr className="dots" />To sum up, by using Apollo we get a way to use GraphQL queries and mutations and an included global state manager! The latter was the main selling point for me.**Look at an example project [here](https://github.com/NeoCoast/react-apollo-example)!**