首页
/ GraphQL Yoga与Next.js集成指南

GraphQL Yoga与Next.js集成指南

2025-07-07 02:05:53作者:秋泉律Samson

前言

在现代Web开发中,GraphQL已经成为构建API的热门选择,而Next.js则是React生态中最受欢迎的SSR框架之一。本文将详细介绍如何将GraphQL Yoga(一个功能齐全的GraphQL服务器)与Next.js框架进行集成,帮助开发者快速构建全栈应用。

基础集成

安装依赖

首先需要安装必要的依赖包:

npm install graphql-yoga graphql

创建GraphQL端点

在Next.js应用路由中创建GraphQL端点非常简单:

// app/api/graphql/route.ts
import { createSchema, createYoga } from 'graphql-yoga'

const { handleRequest } = createYoga({
  schema: createSchema({
    typeDefs: /* GraphQL */ `
      type Query {
        greetings: String
      }
    `,
    resolvers: {
      Query: {
        greetings: () => '欢迎使用GraphQL Yoga与Next.js集成'
      }
    }
  }),
  graphqlEndpoint: '/api/graphql',
  fetchAPI: { Response }
})

export { handleRequest as GET, handleRequest as POST, handleRequest as OPTIONS }

这段代码创建了一个简单的GraphQL服务,提供了一个返回欢迎信息的查询字段。

传统页面目录支持

如果你的项目仍在使用Next.js的传统页面目录结构,集成方式略有不同:

// pages/api/graphql.ts
import { createSchema, createYoga } from 'graphql-yoga'

export const config = {
  api: {
    bodyParser: false  // 禁用body解析,支持文件上传等功能
  }
}

export default createYoga({
  schema: createSchema({
    typeDefs: /* GraphQL */ `
      type Query {
        greetings: String
      }
    `,
    resolvers: {
      Query: {
        greetings: () => '传统页面目录下的GraphQL服务'
      }
    }
  }),
  graphqlEndpoint: '/api/graphql'
})

高级功能:WebSocket订阅支持

GraphQL Yoga支持通过WebSocket实现实时订阅功能,但在Next.js中需要一些额外配置。

安装额外依赖

npm install ws graphql-ws

创建自定义服务器

由于Next.js API路由不支持WebSocket,我们需要创建一个自定义服务器:

// server.js
const { createServer } = require('http')
const { WebSocketServer } = require('ws')
const { createYoga, createSchema } = require('graphql-yoga')
const { useServer } = require('graphql-ws/use/ws')
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const port = 3000

// 准备Next.js应用
const app = next({ dev, port })
const handle = app.getRequestHandler()

// 创建Yoga实例
const yoga = createYoga({
  graphqlEndpoint: '/api/graphql',
  schema: createSchema({
    typeDefs: /* GraphQL */ `
      type Query {
        time: String!
      }
      type Subscription {
        clock: String!
      }
    `,
    resolvers: {
      Query: {
        time: () => new Date().toString()
      },
      Subscription: {
        clock: {
          async *subscribe() {
            while (true) {
              yield { clock: new Date().toString() }
              await new Promise(resolve => setTimeout(resolve, 1000))
            }
          }
        }
      }
    }
  })
})

// 启动应用
app.prepare().then(() => {
  const server = createServer(async (req, res) => {
    try {
      if (req.url.startsWith('/api/graphql')) {
        await yoga(req, res)
      } else {
        await handle(req, res)
      }
    } catch (err) {
      console.error('请求处理错误:', err)
      res.statusCode = 500
      res.end()
    }
  })

  // 创建WebSocket服务器
  const wsServer = new WebSocketServer({ server, path: '/api/graphql' })
  useServer(
    {
      execute: (args) => args.rootValue.execute(args),
      subscribe: (args) => args.rootValue.subscribe(args),
      onSubscribe: async (ctx, msg) => {
        const { schema, execute, subscribe, contextFactory } = yoga.getEnveloped(ctx)
        return {
          schema,
          operationName: msg.payload.operationName,
          document: msg.payload.query,
          variableValues: msg.payload.variables,
          contextValue: await contextFactory(),
          rootValue: { execute, subscribe }
        }
      }
    },
    wsServer
  )

  server.listen(port, () => {
    console.log(`服务器已启动:
    HTTP服务运行在 http://localhost:${port}
    WebSocket服务运行在 ws://localhost:${port}/api/graphql`)
  })
})

运行服务器

启动自定义服务器:

node server.js

最佳实践建议

  1. 环境变量管理:将端口号和端点路径等配置项提取到环境变量中
  2. 错误处理:为生产环境添加更完善的错误处理逻辑
  3. 性能优化:考虑添加查询缓存和批处理功能
  4. 安全考虑:实现适当的认证和授权机制

结语

通过本文的介绍,我们了解了如何在Next.js应用中集成GraphQL Yoga,从基础查询到高级的实时订阅功能。这种组合为开发者提供了强大的工具集,可以构建从简单到复杂各种规模的全栈应用。