Skip to content

How to use graphql with apollo client

Image of the author

David Cojocaru @cojocaru-david

How to Use GraphQL with Apollo Client visual cover image

Mastering GraphQL with Apollo Client: A Comprehensive Guide

GraphQL has transformed how developers handle data in modern applications, and pairing it with Apollo Client unlocks a powerful and efficient approach to frontend development. This guide will provide a deep dive into using GraphQL with Apollo Client, covering everything from initial setup to advanced techniques for querying, mutating, and managing your data effectively. We’ll also explore key best practices to ensure your applications are performant and maintainable.

Why Choose Apollo Client for GraphQL?

Apollo Client is a robust, all-in-one state management solution designed specifically for GraphQL. It offers a multitude of benefits that simplify data fetching and manipulation:

Setting Up Apollo Client in Your Project

Before you can start querying your data, you’ll need to configure Apollo Client in your project. Here’s a step-by-step guide:

Installation

Install the necessary packages using your preferred package manager:

npm install @apollo/client graphql

Initializing the Apollo Client

Create a new Apollo Client instance and configure it to connect to your GraphQL API endpoint.

import { ApolloClient, InMemoryCache } from "@apollo/client";

const client = new ApolloClient({
  uri: "https://your-graphql-endpoint.com/api", // Replace with your GraphQL API endpoint
  cache: new InMemoryCache(),
});

Wrapping Your Application with ApolloProvider

To make the Apollo Client instance accessible throughout your application, wrap your root component with the ApolloProvider component.

import { ApolloProvider } from "@apollo/client";

function App() {
  return (
    <ApolloProvider client={client}>
      <YourApp /> {/* Your application's root component */}
    </ApolloProvider>
  );
}

This makes the client instance available to all components within YourApp via the useQuery and useMutation hooks.

Fetching Data with GraphQL Queries using useQuery

Apollo Client’s useQuery hook simplifies data fetching in your React components.

Basic Query Example

import { gql, useQuery } from "@apollo/client";

const GET_USERS = gql`
  query GetUsers {
    users {
      id
      name
      email
    }
  }
`;

function UsersList() {
  const { loading, error, data } = useQuery(GET_USERS);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <ul>
      {data?.users?.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

Passing Variables to Queries

For dynamic data fetching, use query variables.

import { gql, useQuery } from "@apollo/client";

const GET_USER = gql`
  query GetUser($id: ID!) {
    user(id: $id) {
      name
      email
    }
  }
`;

function UserProfile({ userId }) {
  const { loading, error, data } = useQuery(GET_USER, {
    variables: { id: userId },
  });

  if (loading) return <p>Loading user...</p>;
  if (error) return <p>Error loading user: {error.message}</p>;

  return (
    <div>
      <h1>{data?.user?.name}</h1>
      <p>{data?.user?.email}</p>
    </div>
  );
}

Modifying Data with Mutations using useMutation

Use the useMutation hook to perform create, update, or delete operations.

Basic Mutation Example

import { gql, useMutation } from "@apollo/client";

const ADD_USER = gql`
  mutation AddUser($name: String!, $email: String!) {
    addUser(name: $name, email: $email) {
      id
      name
    }
  }
`;

function AddUserForm() {
  const [addUser, { data, loading, error }] = useMutation(ADD_USER);

  const handleSubmit = async (name, email) => {
    await addUser({ variables: { name, email } });
  };

  if (loading) return <p>Adding user...</p>;
  if (error) return <p>Error adding user: {error.message}</p>;

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        handleSubmit(e.target.name.value, e.target.email.value);
      }}
    >
      <label htmlFor="name">Name:</label>
      <input type="text" id="name" name="name" />
      <br />
      <label htmlFor="email">Email:</label>
      <input type="email" id="email" name="email" />
      <br />
      <button type="submit">Add User</button>
      {data && <p>User added successfully!</p>}
    </form>
  );
}

Advanced Features for Enhanced Performance

Optimistic UI Updates

Improve the user experience by immediately updating the UI with an optimistic response before the server confirms the change.

addUser({
  variables: { name, email },
  optimisticResponse: {
    __typename: "Mutation", // Added the missing typename
    addUser: {
      __typename: "User", //Added typename to the returned type
      id: "temp-id",
      name,
      email,
    },
  },
});

Subscriptions for Real-Time Data

Use GraphQL subscriptions with the useSubscription hook to receive live updates from the server.

import { gql, useSubscription } from "@apollo/client";

const MESSAGES_SUBSCRIPTION = gql`
  subscription OnMessageAdded {
    messageAdded {
      id
      text
    }
  }
`;

function Chat() {
  const { loading, error, data } = useSubscription(MESSAGES_SUBSCRIPTION);

  if (loading) return <p>Loading messages...</p>;
  if (error) return <p>Error loading messages: {error.message}</p>;

  return <ul>{data?.messageAdded && <li>{data.messageAdded.text}</li>}</ul>;
}

Best Practices for Efficient GraphQL and Apollo Client Development

Conclusion

By mastering how to use GraphQL with Apollo Client, you can build robust, efficient, and scalable applications with ease. From declarative data fetching to real-time updates, Apollo Client provides a comprehensive suite of tools that streamline the development process and empower you to create exceptional user experiences. Embrace these techniques and best practices to unlock the full potential of GraphQL and Apollo Client in your projects.

“GraphQL and Apollo Client provide a powerful combination for modern web development, enabling developers to build efficient, data-driven applications with improved performance and maintainability.”