Query Graphql With Apollo Client React GraphQL React Typescript

Apr 29th, 2022 - written by Kimserey with .

Apollo client allows us to easily manage our GraphQL queries and data from the clientside. It provides functionalities such as caching, loading state and data propagation to components and most importantly; is compatible with all major UI frameworks. In today’s post, we’ll look at how we can simply hook Apollo client in a React application and use it to query our GraphQL server.

Simple Server

We start first by re-creating our previous server using Apollo server (if you haven’t done that, you can follow our previous post).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import { ApolloServer, gql } from "apollo-server";

const typeDefs = gql`
  type Person {
    id: ID!
    name: String!
  }

  type Book {
    title: String
    author: Person
  }

  type Query {
    books: [Book]
  }
`;

const resolvers = {
  Query: {
    books: () => [
      {
        title: "Made of Wolves",
        authorId: "1",
      },
      {
        title: "The Visitor in the City",
        authorId: "2",
      },
    ],
  },
  Book: {
    author: (parent: any) => {
      return {
        id: parent.authorId,
        name: parent.authorId == "1" ? "James Carter" : "Arthur Novotic",
      };
    },
  },
};

async function main() {
  const server = new ApolloServer({ typeDefs, resolvers });
  await server.listen(4000);
  console.log("Server started on http://localhost:4000");
}

main();

This will setup a GraphQL server with a single query books and a field resolver for Book.author. We can now start to build our frontend to query our server.

Setup Apollo Client

We start first by installing Apollo client:

1
npm install @apollo/client graphql

And we then create a client in our index.tsx file:

1
2
3
4
5
6
7
8
9
10
11
12
import {
  ApolloClient,
  InMemoryCache,
  ApolloProvider,
  useQuery,
  gql,
} from "@apollo/client";

const client = new ApolloClient({
  uri: "http://localhost:4000",
  cache: new InMemoryCache(),
});

If we add a query on the client, we can test that the client is working:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
client
  .query({
    query: gql`
      query Query {
        books {
          title
          author {
            id
            name
          }
        }
      }
    `,
  })
  .then((result) => console.log(result));

And we’ll see the result in the console.

Query Server With Query Hook

Now querying directly with the client isn’t the recommended way. Instead, we’ll use the build-in hooks provided. For us as we have a query, we’ll use useQuery.

Before being able to use hooks, we need to register the client by wrapping our app into the ApolloProvider:

1
2
3
4
5
6
7
8
9
10
11
12
13
const client = new ApolloClient({
  uri: "http://localhost:4000",
  cache: new InMemoryCache(),
});

ReactDOM.render(
  <React.StrictMode>
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

And we can then use useQuery:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import { gql, useQuery } from "@apollo/client";
import React, { FC } from "react";

const BOOKS = gql`
  query GetBooks {
    books {
      title
      author {
        id
        name
      }
    }
  }
`;

const TestComp: FC = () => {
  const { data, loading, error } = useQuery<{
    books: { title: string; author: { id: string; name: string } }[];
  }>(BOOKS);

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

  return (
    <>
      {data &&
        data.books.map((b) => {
          return (
            <div>
              {b.title} - {b.author.name}
            </div>
          );
        })}
    </>
  );
};

function App() {
  return (
    <div className="App">
      <TestComp></TestComp>
    </div>
  );
}

export default App;

We can see that useQuery takes a gql query as parameter, which is the definition of our GraphQL query. The advantage of using useQuery hook is tha data, loading and error will get update as the client queries the data which will in turn trigger a rendering of the component.

This allows us to create specific logic to handle querying, error state and display of data.

Other than the useQuery hook, we also have access to the useMutation hook for GraphQL mutations and plenty of other configurations for the client.

And that concludes today’s post!

Conclusion

Today we looked at how we could setup Apollo Client to query a GraphQL server. We started by a quick recap on setting up a server and then moved on to setup Apollo Client and completed the post by looking at the query hook provided by Apollo Client. I hope you liked this post and I’ll see you on the next one!

External Sources

Designed, built and maintained by Kimserey Lam.