如何在Next.js中添加服务端GraphQL Subscriptions?(Apollo Server micro场景)
解决Next.js + Apollo Server micro无法实现GraphQL订阅的问题
由于apollo-server-micro本身不支持GraphQL订阅(Subscription)功能,你可以通过以下方案实现实时更新:
方案一:改用Apollo Server + Express + WebSocket
该方案通过将Apollo Server与Express结合,利用subscriptions-transport-ws实现WebSocket订阅支持,同时兼容Next.js的API路由。
步骤1:安装依赖
npm install apollo-server-express express ws graphql-subscriptions subscriptions-transport-ws
步骤2:修改/api/graphql路由代码
替换原有的apollo-server-micro相关代码,改为以下实现:
import express from 'express'; import { ApolloServer } from 'apollo-server-express'; import { createServer } from 'http'; import { SubscriptionServer } from 'subscriptions-transport-ws'; import { execute, subscribe } from 'graphql'; import micro_cors from 'micro-cors'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { typeDefs } from 'graphql/typeDefsUnion'; import { resolvers } from 'graphql/resoversUnion'; const cors = micro_cors({ origin: "https://studio.apollographql.com", allowMethods: ["GET", "POST"], allowHeaders: [ "Access-Control-Allow-Credentials", "true", "Content-Type", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers" ] }); // 创建可执行Schema const schema = makeExecutableSchema({ typeDefs, resolvers }); // 创建Express实例 const app = express(); const httpServer = createServer(app); // 配置Apollo Server const apolloServer = new ApolloServer({ schema, context: ({ req, res }) => ({ req, res }) }); // 初始化Apollo Server并应用到Express await apolloServer.start(); apolloServer.applyMiddleware({ app, path: '/api/graphql' }); // 配置Subscription Server SubscriptionServer.create( { schema, execute, subscribe }, { server: httpServer, path: apolloServer.graphqlPath } ); // 处理Next.js API路由的请求 export default cors(async function handler(req, res) { if (req.method === 'OPTIONS') { res.end(); return false; } // 将请求转发给Express处理 await new Promise((resolve, reject) => { app(req, res, (err) => { if (err) reject(err); else resolve(); }); }); }); export const config = { api: { bodyParser: false, }, };
方案二:单独搭建WebSocket服务器处理订阅
如果不想改动现有Apollo Server micro的HTTP请求处理,可以单独启动一个WebSocket服务器,专门处理GraphQL订阅请求。
步骤1:安装依赖
npm install ws graphql-subscriptions subscriptions-transport-ws
步骤2:创建WebSocket服务器文件(比如server/subscriptionServer.js)
import { createServer } from 'http'; import { SubscriptionServer } from 'subscriptions-transport-ws'; import { execute, subscribe } from 'graphql'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { typeDefs } from '../graphql/typeDefsUnion'; import { resolvers } from '../graphql/resoversUnion'; const schema = makeExecutableSchema({ typeDefs, resolvers }); const httpServer = createServer((req, res) => { res.writeHead(404); res.end(); }); SubscriptionServer.create( { schema, execute, subscribe }, { server: httpServer, path: '/subscriptions' } ); const PORT = 4000; httpServer.listen(PORT, () => { console.log(`Subscription server running on ws://localhost:${PORT}/subscriptions`); });
步骤3:启动WebSocket服务器
在package.json中添加启动脚本:
{ "scripts": { "start:subscriptions": "node server/subscriptionServer.js" } }
运行npm run start:subscriptions启动订阅服务器,前端客户端通过ws://localhost:4000/subscriptions连接订阅。
注意事项
- 前端客户端需要使用
subscriptions-transport-ws或者@apollo/client的WebSocketLink来连接订阅服务器。 - 如果部署到生产环境,需要确保WebSocket端口对外开放,或者使用反向代理(如Nginx)转发WebSocket请求。
内容的提问来源于stack exchange,提问作者Mansour Ahmed
相关产品推荐
相关产品推荐

