You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js客户端拼接GraphCMS远程Schema时遇watchQuery函数错误求助

解决Next.js客户端拼接GraphCMS端点时的watchQuery is not a function错误

看起来你是把服务端Schema聚合的逻辑错放到客户端Apollo Client初始化里了——这就是问题的核心!makeRemoteExecutableSchema和mergeSchemas是用来在服务端搭建GraphQL网关的工具,客户端的Apollo Client根本不认识这些Schema级别的操作,自然找不到watchQuery方法。下面给你两种可行的解决思路:

思路一:客户端直接路由请求到不同端点(无需Schema合并)

如果不想额外搭建服务端网关,可以用Apollo Client的split方法,根据请求的内容把查询路由到对应的GraphCMS端点:

// initApollo.js
import { ApolloClient, InMemoryCache, HttpLink, split } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';

// 定义两个GraphCMS端点的HttpLink
const cmsLink1 = new HttpLink({ uri: 'https://your-first-graphcms-endpoint.com' });
const cmsLink2 = new HttpLink({ uri: 'https://your-second-graphcms-endpoint.com' });

// 根据查询的内容判断走哪个端点
const splitLink = split(
  ({ query }) => {
    const definition = getMainDefinition(query);
    // 示例:如果查询的是"posts"字段,走第一个端点;其他走第二个
    return (
      definition.kind === 'OperationDefinition' &&
      definition.selectionSet.selections.some(sel => sel.name.value === 'posts')
    );
  },
  cmsLink1,
  cmsLink2
);

export default function initApollo() {
  return new ApolloClient({
    ssrMode: typeof window === 'undefined',
    link: splitLink,
    cache: new InMemoryCache(),
  });
}

思路二:在Next.js服务端搭建GraphQL网关(推荐多端点聚合场景)

如果需要真正合并多个GraphCMS的Schema(比如解决字段冲突、统一查询入口),可以在Next.js的API路由里搭建一个网关:

1. 创建网关API路由

// pages/api/graphql.js
import { ApolloServer } from 'apollo-server-micro';
import { makeRemoteExecutableSchema, mergeSchemas, introspectSchema } from '@graphql-tools/schema';
import { HttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';

async function buildGatewaySchema() {
  // 拉取并处理第一个GraphCMS端点的Schema
  const cmsLink1 = new HttpLink({ uri: 'https://your-first-graphcms-endpoint.com', fetch });
  const cmsSchema1 = await introspectSchema(cmsLink1);
  const executableSchema1 = makeRemoteExecutableSchema({ schema: cmsSchema1, link: cmsLink1 });

  // 处理第二个GraphCMS端点的Schema
  const cmsLink2 = new HttpLink({ uri: 'https://your-second-graphcms-endpoint.com', fetch });
  const cmsSchema2 = await introspectSchema(cmsLink2);
  const executableSchema2 = makeRemoteExecutableSchema({ schema: cmsSchema2, link: cmsLink2 });

  // 合并两个可执行Schema(字段冲突时可以在这里自定义resolver处理)
  return mergeSchemas({
    schemas: [executableSchema1, executableSchema2],
  });
}

let apolloServer;

export default async function handler(req, res) {
  if (!apolloServer) {
    const gatewaySchema = await buildGatewaySchema();
    apolloServer = new ApolloServer({ schema: gatewaySchema });
    await apolloServer.start();
  }

  await apolloServer.createHandler({ path: '/api/graphql' })(req, res);
}

// 禁用Next.js默认的body解析,交给Apollo Server处理
export const config = {
  api: {
    bodyParser: false,
  },
};

2. 客户端指向本地网关

修改你的initApollo.js,让客户端请求这个本地网关端点:

// initApollo.js
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client';

export default function initApollo() {
  return new ApolloClient({
    ssrMode: typeof window === 'undefined',
    link: new HttpLink({ uri: '/api/graphql' }),
    cache: new InMemoryCache(),
  });
}

额外注意:版本兼容性

确保你的依赖包版本统一:现在Apollo Client的官方包是@apollo/client,旧版的apollo-client已经不再维护,和@graphql-tools/schema这类工具可能存在兼容性问题,建议把依赖都升级到最新稳定版。

内容的提问来源于stack exchange,提问作者Will Meier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:23:29