⚠️
Warning
This is the documentation for the old GraphQL Yoga v3.
We recommend
upgrading to the latest GraphQL Yoga v5. Migrate to GraphQL Yoga
v5.
Integration with Next.js
Next.js is a web framework that allows you to build websites very quickly and GraphQL Yoga can be integrated with Next.js easily as an API Route .
Installation
Terminal
yarn add graphql
yarn add graphql-yoga
Example
pages/api/graphql.ts
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import { createYoga, createSchema } from 'graphql-yoga'
import type { NextApiRequest, NextApiResponse } from 'next'
export const config = {
api: {
// Disable body parsing (required for file uploads)
bodyParser: false
}
}
const schema = createSchema({
typeDefs: /* GraphQL */ `
type Query {
greetings: String
}
`,
resolvers: {
Query: {
greetings: () => 'This is the `greetings` field of the root `Query` type'
}
}
})
export default createYoga<{
req: NextApiRequest
res: NextApiResponse
}>({
schema,
// Needed to be defined explicitly because our endpoint lives at a different path other than `/graphql`
graphqlEndpoint: '/api/graphql'
})
You can also check a full example on our GitHub repository here
WebSockets for subscriptions
WebSockets cannot be used with Next.js API Routes , we therefore have to create a custom Next.js server that will serve the GraphQL API, WebSockets and the rest of Next.js content.
Installation
Terminal
yarn add graphql
yarn add graphql-yoga
yarn add ws
yarn add graphql-ws
Example
server.js
const { createServer } = require('http')
const { WebSocketServer } = require('ws')
const { createYoga, createSchema } = require('graphql-yoga')
const { useServer } = require('graphql-ws/lib/use/ws')
const { parse } = require('url')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const hostname = 'localhost'
const port = 3000
// prepare nextjs
const app = next({ dev, hostname, port })
// match the route next would use if yoga was in `pages/api/graphql.ts`
const graphqlEndpoint = '/api/graphql'
// prepare yoga
const yoga = createYoga({
graphqlEndpoint,
graphiql: {
subscriptionsProtocol: 'WS'
},
schema: createSchema({
typeDefs: /* GraphQL */ `
type Query {
hello: String!
}
type Subscription {
clock: String!
}
`,
resolvers: {
Query: {
hello: () => 'world'
},
Subscription: {
clock: {
async *subscribe() {
for (let i = 0; i < 5; i++) {
yield { clock: new Date().toString() }
await new Promise((resolve) => setTimeout(resolve, 1_000))
}
}
}
}
}
})
})
;(async () => {
await app.prepare()
const handle = app.getRequestHandler()
// create http server
const server = createServer(async (req, res) => {
try {
// Be sure to pass `true` as the second argument to `url.parse`.
// This tells it to parse the query portion of the URL.
const url = parse(req.url, true)
if (url.pathname.startsWith(graphqlEndpoint)) {
await yoga(req, res)
} else {
await handle(req, res, url)
}
} catch (err) {
console.error(`Error while handling ${req.url}`, err)
res.writeHead(500).end()
}
})
// create websocket server
const wsServer = new WebSocketServer({ server, path: graphqlEndpoint })
// prepare graphql-ws
useServer(
{
execute: (args) => args.rootValue.execute(args),
subscribe: (args) => args.rootValue.subscribe(args),
onSubscribe: async (ctx, msg) => {
const { schema, execute, subscribe, contextFactory, parse, validate } =
yoga.getEnveloped(ctx)
const args = {
schema,
operationName: msg.payload.operationName,
document: parse(msg.payload.query),
variableValues: msg.payload.variables,
contextValue: await contextFactory(),
rootValue: {
execute,
subscribe
}
}
const errors = validate(args.schema, args.document)
if (errors.length) return errors
return args
}
},
wsServer
)
await new Promise((resolve, reject) =>
server.listen(port, (err) => (err ? reject(err) : resolve()))
)
console.log(`
> App started!
HTTP server running on http://${hostname}:${port}
GraphQL WebSocket server running on ws://${hostname}:${port}${graphqlEndpoint}
`)
})()
Running Next.js
Now that we have the custom server implemented, you start it by running:
node server.js
You can also check a full example on our GitHub repository here