Next.js App Router中Apollo GraphQL 405错误及路由导出问题求助
Next.js App Router 集成 Apollo Server/Client 问题排查与修复
问题情况
- 终端报错:
..\app\api\graphql\route.ts中未导出HTTP方法,请为每个HTTP方法导出命名导出 - 浏览器报错:
Response not successful: Received status code 405 - 疑问:
ApolloClient.ts、typeDefs.ts、resolver.ts、graphql.ts放在app/api/graphql目录下的结构是否正确
文件结构说明
当前结构存在核心问题:Next.js App Router 的 API 路由必须以route.ts作为入口文件,你现在用graphql.ts作为服务端入口不符合路由规则。调整后的推荐结构如下:
app/ └── api/ └── graphql/ ├── route.ts # API路由入口(必填) ├── ApolloClient.ts # Apollo客户端配置 ├── typeDefs.ts # GraphQL类型定义 └── resolver.ts # 解析器实现
注:ApolloClient.ts也可以移到项目根目录的lib文件夹下,更符合常规项目结构规范。
现有代码文件
ApolloClient.ts
import { ApolloClient, HttpLink, InMemoryCache } from "@apollo/client"; import { registerApolloClient } from "@apollo/experimental-nextjs-app-support/rsc"; export const { getClient } = registerApolloClient(() => { return new ApolloClient({ cache: new InMemoryCache(), link: new HttpLink({ uri: "http://localhost:3000/api/graphql", }), }); });
typeDefs.ts
import { gql } from "graphql-tag"; const typeDefs = gql` type Query { hello: String } `; export default typeDefs;
注:文件中不需要导入ApolloServer,可以删除该行冗余代码。
resolver.ts
const resolvers = { Query: { hello: () => 'world', }, }; export default resolvers;
graphql.ts(原服务端入口)
import { ApolloServer } from "@apollo/server"; import typeDefs from './typeDefs'; import resolvers from './resolvers'; import { startServerAndCreateNextHandler } from "@as-integrations/next"; const graphql = new ApolloServer({ resolvers, typeDefs }); export default startServerAndCreateNextHandler(graphql);
浏览器报错栈
Unhandled Runtime Error Error: Response not successful: Received status code 405 Call Stack new ApolloError (rsc)\node_modules\@apollo\client\errors\index.js (39:0) eval (rsc)\node_modules\@apollo\client\core\QueryManager.js (777:37) both (rsc)\node_modules\@apollo\client\utilities\observables\asyncMap.js (22:0) eval (rsc)\node_modules\@apollo\client\utilities\observables\asyncMap.js (11:56) new Promise <anonymous> Object.then (rsc)\node_modules\@apollo\client\utilities\observables\asyncMap.js (11:0) Object.eval [as error] (rsc)\node_modules\@apollo\client\utilities\observables\asyncMap.js (24:0) notifySubscription (rsc)\node_modules\zen-observable-ts\module.js (137:0) onNotify (rsc)\node_modules\zen-observable-ts\module.js (176:0) SubscriptionObserver.error (rsc)\node_modules\zen-observable-ts\module.js (229:0) eval (rsc)\node_modules\@apollo\client\utilities\observables\iteration.js (7:49) Array.forEach <anonymous> iterateObserversSafely (rsc)\node_modules\@apollo\client\utilities\observables\iteration.js (7:0) Object.error (rsc)\node_modules\@apollo\client\utilities\observables\Concast.js (76:42) notifySubscription (rsc)\node_modules\zen-observable-ts\module.js (137:0) onNotify (rsc)\node_modules\zen-observable-ts\module.js (176:0) SubscriptionObserver.error (rsc)\node_modules\zen-observable-ts\module.js (229:0) handleError (rsc)\node_modules\@apollo\client\link\http\parseAndCheckHttpResponse.js (170:0) eval (rsc)\node_modules\@apollo\client\link\http\createHttpLink.js (145:27) process.processTicksAndRejections node:internal/process/task_queues (95:5)
修复步骤
1. 调整服务端路由入口
将原graphql.ts重命名为route.ts,并修改导出方式——Next.js App Router要求API路由必须显式导出对应HTTP方法的处理函数。修改后的代码如下:
import { ApolloServer } from "@apollo/server"; import typeDefs from './typeDefs'; import resolvers from './resolver'; import { startServerAndCreateNextHandler } from "@as-integrations/next"; const server = new ApolloServer({ resolvers, typeDefs }); const handler = startServerAndCreateNextHandler(server); // 显式导出GET和POST方法,处理GraphQL请求 export async function GET(request: Request) { return handler(request); } export async function POST(request: Request) { return handler(request); }
2. 清理冗余代码
删除typeDefs.ts中不必要的import { ApolloServer } from "@apollo/server";语句,因为该文件只负责定义GraphQL类型,不需要导入ApolloServer。
错误原因说明
- 终端提示的未导出HTTP方法错误:Next.js App Router的API路由强制要求在
route.ts中通过命名导出(如export async function GET())定义支持的HTTP方法,原代码用默认导出且文件名不符合要求,导致路由无法识别。 - 405状态码错误:因为API路由没有处理客户端发送的POST/GET请求(GraphQL主要用POST),服务器返回“方法不允许”的响应,最终触发Apollo客户端的错误。
内容的提问来源于stack exchange,提问作者user17449555
相关产品推荐
相关产品推荐

