Getting Started with Next.js, GraphQL and React Query (1/3)

Preston Kelly
Preston KellyWednesday, September 28, 2022
Aerial view of a circular highway


Add a GraphQL endpoint, and wrap your app with QueryClientProvider from @tanstack/react-query. Next, create an async function and use GraphQLClient from graphql-request to request data.

Create Next App

Start by creating a basic Next.js app with the following command, npx create-next-app@latest --ts . This command will create a new Next.js app with a TypeScript configuration, hence the --ts flag. Head to the /pages directory and you'll notice an index.tsx page and an _app.tsx page. You'll see an /api directory. This is where we'll add our GraphQL server.

Let’s transition to configuring the server. Create a new file in the /api directory and name it graphql.ts. This file will serve as the single endpoint we need for GraphQL. To import GraphQL we'll need 3 packages. Install these packages with this command npm install apollo-server-micro micro graphql.

Inside our new file, we are going to create our GraphQL types and resolvers. In a typical app, you’d want to create a new file for these and import them elsewhere in the app. For this app, we'll create our types and resolvers in the same file. Let’s create a User type that has an id, firstName and lastName field. We’ll also add a Query type, which we will need when we create our resolver.

// pages/api/graphql.ts const typeDefs = gql` type User { id: ID firstName: String lastName: String } type Query { getUser: User } `;

The next step is to create the resolvers or in other words, tell GraphQL where to look for the data. In most cases, the resolvers will connect to your database or an external API source. In our case, we’ll return some hard-coded data. I’ll add an id of 1, a firstName of “Hello” and a lastName of “World”. Now that we have our types and resolvers set up, the next step is to pass these to ApolloServer.

// pages/api/graphql.ts const resolvers = { Query: { getUser: () => ({ id: "1", firstName: "Hello", lastName: "World" }), }, }; const apolloServer = new ApolloServer({ typeDefs, resolvers, });

The final step is to create our handler function that will become our Next.js API route. Inside this handler function, we have to do two things. The first is to start the server. We then have to use apolloServer.createHandler to connect Apollo Server to Next.js. We’ll also disable bodyParser since this is handled by default in GraphQL.

// pages/api/graphql.ts import { gql, ApolloServer } from "apollo-server-micro"; import { NextApiRequest, NextApiResponse, PageConfig } from "next"; const typeDefs = gql` type User { id: ID firstName: String lastName: String } type Query { getUser: User } `; const resolvers = { Query: { getUser: () => ({ id: "1", firstName: "Hello", lastName: "World" }), }, }; const apolloServer = new ApolloServer({ typeDefs, resolvers, }); const startServer = apolloServer.start(); export default async function handler( req: NextApiRequest, res: NextApiResponse ) { await startServer; await apolloServer.createHandler({ path: "/api/graphql", })(req, res); } export const config: PageConfig = { api: { bodyParser: false, }, };

React Query

Let’s switch to the front end so that we can add React Query to our app. To begin, we'll need some packages for React Query. Install the packages we need with this command npm install graphql-request @tanstack/react-query. Head over to /pages/_app.tsx and create a QueryClient imported from @tanstack/react-query. We’ll wrap our app with QueryClientProvider, passing our QueryClient as the client parameter. This will allow us to access React Query throughout our entire app.

// pages/_app.tsx import "../styles/globals.css"; import type { AppProps } from "next/app"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; // Create a client const queryClient = new QueryClient(); function MyApp({ Component, pageProps }: AppProps) { return ( <QueryClientProvider client={queryClient}> <Component {...pageProps} /> </QueryClientProvider> ); } export default MyApp;

We can now create a function that will allow us to query for our user on the back end. We’ll use GraphQLClient and pass in the GraphQL endpoint that we made. We can then use this to make requests. To query for our user, we need to add a gql statement and pass it as a parameter to a graphQLClient request. We’ll then use this function by passing it to React Query’s useQuery hook, along with a key get-user. From this hook, I’ve destructured the isLoading state and the data. I’ve added an if statement to check if the data is loading. All we have to do now is display the data using some styling from Tailwind and a couple of p tags.

// pages/index.tsx import type { NextPage } from "next"; import { useQuery } from "@tanstack/react-query"; import { GraphQLClient, gql } from "graphql-request"; const UserQuery = gql` query getUser { getUser { id firstName lastName } } `; const graphQLClient = new GraphQLClient("http://localhost:3000/api/graphql"); const fetchUser = async () => { return await graphQLClient.request(UserQuery); }; const Home: NextPage = () => { const { isLoading, data } = useQuery(["get-user"], fetchUser); if (isLoading) return <p>Loading...</p>; return ( <> <div className="flex h-screen w-screen justify-center items-center"> <div> <p>{}</p> <p>{data.getUser.firstName}</p> <p>{data.getUser.lastName}</p> </div> </div> </> ); }; export default Home;


As you can see, adding GraphQL to a Next.js app takes only a few steps. Today, we created a Next.js app with a TypeScript configuration. We created a GraphQL server with types and resolvers, and added React Query to query for our hard-coded data. I encourage you to extend this project. Create a new type, create a resolver for that type, and add a new function to query for that data using React Query.


Share this post


Related Posts:

Interested in working with us?

Give us some details about your project, and our team will be in touch with how we can help.

Get in Touch