Unlock the Power of Next.js: Building a Scalable GraphQL Server
Next.js is often misunderstood as just a frontend React framework, but it offers so much more. With its API routes, you can easily create a backend to your React frontend code, all within the same application. In this article, we’ll explore how to set up a GraphQL API within Next.js, leveraging TypeScript, Prisma, and Nexus to create a fully typed and efficient setup.
Setting Up Next.js
To get started, run yarn create next-app
and modify the tsconfig.json
file to enforce stricter TypeScript rules. You can find the full list of packages used in this article in the package.json
file.
Configuring Prisma
Prisma will be our tool of choice for loading data from our Postgres database. Run npx prisma init
to generate a prisma
folder containing a schema.prisma
file. Update the schema file to include two models: Album
and Artist
. Then, create and run a database migration using npx prisma migrate dev --name init
.
Loading Seed Data
When developing locally, it’s essential to have consistent seed data. Update the scripts
section in your package.json
file to include a ts-node
script, required to execute the Prisma seed command. Create a seed.ts
file in the prisma
folder to generate data for local development. Finally, run npx prisma db seed --preview-feature
to populate your local database.
Adding an API Route in GraphQL
Create a file called graphql.ts
within the pages/api
folder. For now, its contents will simply respond with the text “GraphQL!”. But with this setup, you could respond with any JSON data, reading query params, headers, etc. from the req
object.
GraphQL Context
Every resolver in GraphQL receives a context, which is a place to put global things like an authenticated user, database connection (Prisma), and DataLoader (to avoid N+1 queries). We’ll start by exporting a context function that returns an instance of the Prisma client.
Setting Up GraphQL Schema
With our context in place, it’s time to generate our GraphQL schema using Nexus. We’ll create three GraphQL types: Query
, Artist
, and Album
. The key sections of this makeSchema
call include outputs, sourceTypes, contextType, and nonNullDefaults.
Top-Level Query Type
The Query
type is one of the top-level fields of your GraphQL API, along with Mutation
and Subscription
. We’ll define one field: albums
, which will use the Prisma client from our context to load the albums.
Avoiding N+1 Queries with DataLoader
To avoid the hidden problem of loading the artist for each album, we’ll define a loader function to pool up IDs (of artists) and load them all at once in a single batch. This allows us to update our Album
type to utilize the DataLoader inside of the artist resolver, resulting in a single query to the database to load all the artists at once.
The Final Result
In this article, we’ve created a typed, code-first GraphQL server in Next.js, loading data from Postgres with Prisma, and eliminating N+1 performance issues using DataLoader. With Next.js, you can easily create a backend to your React frontend code, all within the same application. The next step might involve adding mutations along with authentication to your app, enabling users to create and modify data with the correct permissions.