Setting up an Apollo GraphQL server in Next.js 13

2023-02-10

Unlock the power of GraphQL and Next.js with this comprehensive tutorial! Learn the essentials step-by-step and build better APIs with Apollo and GraphQL.

Tutorial NextJS GraphQL

Contents

Introduction

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

GraphQL has risen to prominence as an alternative to the Representational State Transfer (REST) paradigm which stores data entities under URLs on a server. In comparison, GraphQL uses a schema to allow back-end developers to define the structure of the data to be returned by the server. Then, using this schema, a front-end consumer can explore the available data and request specific data. It solves the problem of over-fetching encountered with REST APIs because it allows the client to specify exactly which data should be returned in a format that resembles JavaScript Object Notation (JSON). However, GraphQL creates a tight coupling between the front and back end that makes it more suitable for use when the front and back-end teams are working closely.

Set Up

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.

https//rescloudinarycom/ta1dacloud/image/upload/v1676035067/realm/tutorials/nextjsgraphql/projectinithwnsr0png

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

According to their website, Apollo Client is a 'state management library for JavaScript that enables you to manage both local and remote data with GraphQL'. We will use it to fetch application data and keep the UI up-to-date.

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.

https//rescloudinarycom/ta1dacloud/image/upload/v1676035064/realm/tutorials/nextjsgraphql/apolloclienthas66fpng

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.

https//rescloudinarycom/ta1dacloud/image/upload/v1676035069/realm/tutorials/nextjsgraphql/typedefsb0zntgpng

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.

https//rescloudinarycom/ta1dacloud/image/upload/v1676035226/realm/tutorials/nextjsgraphql/graphqlfolderuf58snpng

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.

https//rescloudinarycom/ta1dacloud/image/upload/v1676035068/realm/tutorials/nextjsgraphql/resolversqm3el3png

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.

https//rescloudinarycom/ta1dacloud/image/upload/v1676035063/realm/tutorials/nextjsgraphql/prismaschemaiu6i7npng

After we create the schema, we must also add some scripts to our package.json that we will use to interact with the database.

https//rescloudinarycom/ta1dacloud/image/upload/v1676035064/realm/tutorials/nextjsgraphql/prismascriptsgqu42zpng

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.

https//rescloudinarycom/ta1dacloud/image/upload/v1676035065/realm/tutorials/nextjsgraphql/createcontextbnkvo6png

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.

https//rescloudinarycom/ta1dacloud/image/upload/v1676035069/realm/tutorials/nextjsgraphql/queryresolverszwz6aqpng

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.

https//rescloudinarycom/ta1dacloud/image/upload/v1676035062/realm/tutorials/nextjsgraphql/apolloserverqxdzvmpng

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.

https//rescloudinarycom/ta1dacloud/image/upload/v1676035065/realm/tutorials/nextjsgraphql/corsconfigoihmuvpng

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.

https//rescloudinarycom/ta1dacloud/image/upload/v1676035227/realm/tutorials/nextjsgraphql/apolloplaygroundzg3ihqpng

https//rescloudinarycom/ta1dacloud/image/upload/v1676035063/realm/tutorials/nextjsgraphql/graphqlquerypl0p2hpng

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.

https//rescloudinarycom/ta1dacloud/image/upload/v1676035068/realm/tutorials/nextjsgraphql/ssrqueryivfa3epng

Conclusion

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). Thanks for reading!

Subscribe

Unsubscribe anytime!