In this tutorial, I will show you how to set up Next.js 13 to serve a GraphQL API with Apollo Server.
What is GraphQL
GraphQL is a query language for reading and mutating data in APIs. It is also a server-side run-time technology for fulfilling queries with existing data. GraphQL was developed at Facebook (now Meta) to deal with some challenges encountered in implementing the News Feed.
Why Use GraphQL over REST
For this tutorial, I will assume that you are familiar with Next.js and GraphQL. You can follow the tutorial from the beginning or clone the starter repo initial branch from GitHub with all the dependencies already installed. We will be building a simple quotes app.
We will use create-next-app to initialise a new Next.js project. Run the command
npx create-next-app [your desired name] and follow the prompts to configure the project.
Then, we install the required dependencies using the command below:
npm install @apollo/client @prisma/client apollo-server-micro graphql micro-cors
We will also install some dev dependencies.
npm install -D @types/micro-cors prisma ts-node
This should be all but if we need anything else we can always install it later.
Creating the Apollo Client
In your project directory, create a folder called lib. This is where we will store various configuration files for our project. Inside this folder create a file called client.ts.
First, we create an instance of HttpLink, passing in the URI for our GraphQL server (we’ll configure this next). Then, we create an instance of ApolloClient by passing in the HttpLink instance and creating a new instance of InMemoryCache. This is used by Apollo Client to cache the results of any given query.
Create the GraphQL server
We will set up the GraphQL server in our pages/api folder to handle our requests. When we create an instance of ApolloServer, we must pass in the type definitions from the GraphQL schema and at least one resolver. We can also pass into the context anything that we wish to be accessible throughout the server. We can create a graphql.ts file inside the /api folder which we will return to after creating the schema and resolvers.
In the root of your project, create a folder called graphql. This is where we will store everything that has to do with GraphQL. Inside that folder, create a schema.ts file where we will define the schema. In the schema, we can define types for our data models and the various queries and mutations that our server will resolve. This is the most important step when we use the schema-first approach to designing GraphQL APIs. In our case, we will have a single Quote data model, and two queries to fetch a list of quotes and a single quote by its ID.
Our quote model has 4 properties, an ID that will be automatically assigned by the database, a string tag, an author, and the content of the quote. All fields are required. The quotes query will return an array of quote objects. We can also return a single quote by passing in an ID.
Within the same folder, create two folders for the resolvers and the methods. This is where we will define the methods to handle our API requests.
We create an index.ts file inside the resolvers folder. It will help with organising our methods if we ever decide to add more resolvers to our project.
As you can see above, if our project had mutations or any other resolvers, it would be very easy to add and manage them.
In our query.ts file, we will implement the methods to retrieve our data from the database. We will be using PrismaORM to run our database queries, so we must make an instance of Prisma Client available to our resolvers via the context.
Initialise Prisma and Create Context
We must first initialise Prisma with the command
npx prisma init. If you cloned the starter, you do not need to run this command. Running prisma init creates a prisma folder in the parent directory with a prisma.schema file and creates or modifies our .env file.
Modify the prisma schema file by changing the provider to mongodb. Prisma can be configured to work with a number of different databases. Just as we did with the GraphQL schema, we will also define the shape of our data as shown below.
After we create the schema, we must also add some scripts to our package.json that we will use to interact with the database.
Run the Prisma Generate command,
npm run prisma:generate to generate the Prisma Client and types according to our schema. The seed command will be used later to add sample data to our database.
Now, we can create our context. Create a context.ts file inside the /lib folder. Inside this file we will create an instance of Prisma Client and use createContext() to make it available to the resolvers.
We can return to our query.ts file and import Context from context.ts. We will define two query methods to handle retrieving a list of quotes and a single quote. These are the queries that we have defined in our GraphQL schema.
Finalise the GraphQL Server
After creating our resolvers and schema, we can return to the graphql.ts file and configure the GraphQL server.
The first step is to update the Next.js page config and set bodyParser to false. This allows our Apollo Server to read the request body instead of Next.js. After that, we create an instance of Apollo Server. We configure the ApolloServer object by adding the context, type definitions, and resolvers. We also set introspection to true. Introspection allows us to query the server about the underlying schema. Ideally, this should be false in a production environment. We can use the start command to start our server.
We also need to configure cors using the
micro-cors package. CORS is an HTTP-based header protocol that allows a server to control which origins can access its resources. In order to use the Apollo Studio, we must allow requests from the Apollo Studio origin. We will also allow it to set certain headers.
Testing the Server
At this point, we should be able to access our server at
http://localhost:3000/api/graphql. From here we can introspect our schema and test the database. If you downloaded the starter repo, you can build the Mongo Replica Set image using the Dockerfile and load up a container with
docker compose up. Or, if you have MongoDB already installed on your machine, you can seed the database using the seed.ts file in the repo with the command
npx prisma db seed. After seeding the database, you can run a query in the Apollo Playground to see if you can retrieve some data from the database.
We can also write the same queries and store them in the /graphql/methods/query.ts file to use them in our application. We can call the
GET_QUOTES method inside getServerSideProps to use SSR in our app.
In conclusion, I hope that this tutorial has been helpful in guiding you through the process of setting up a GraphQL server in Next.js. By following the steps outlined in this tutorial, you should now have a solid understanding that will allow you to use GraphQL in your own Next.js projects. If there’s anything you missed, you can also find the completed project on the
main branch of the GitHub repo, including a sample home page showing how to query the GraphQL server. I encourage you to continue practising and exploring new programming technologies to enhance your skills. If you have any questions or feedback, feel free to reach out to me on Twitter (@edtha3rd). For early access to my posts, check out my website or consider subscribing here so that you never miss a post. Thanks for reading!