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

新版@apollo/server与graphql-tools中Schema拼接与自省问题解决

问题:升级GraphQL网关后远程Schema拼接成功但API返回null

版本升级清单

包名旧版本目标版本
graphql-toolsV4.0.5V9.0.0
apollo-server-expressV2.7.2@apollo/server V4.8.0
expressV4.17.1V4.18.2
graphqlV14.4.2V16.7.1

核心问题

旧版本通过introspectSchema+makeRemoteExecutableSchema+mergeSchemas实现远程Schema拼接,升级后这两个核心函数废弃,改用@graphql-tools/wrap和@graphql-tools/executor-http相关API后,Schema拼接成功且能接收introspection查询,但调用接口时返回null。根源在于:

  • mergeSchemas在v9中对subschema执行器的支持不足,需改用stitchSchemas
  • 请求上下文(如身份头)未正确传递给远程服务
  • Apollo Server v4的上下文传递逻辑需适配新的执行器体系

修复步骤

1. 替换mergeSchemas为stitchSchemas

graphql-tools v9中,mergeSchemas已被stitchSchemas替代,后者更适配subschema的执行器配置:

// 导入替换
import { stitchSchemas } from '@graphql-tools/stitch';

// 修改createSchema函数
const createSchema = async () => {
  const remoteSchemas = [];
  for (let service of servicesList) {
    const retSchema = await utils.getRemoteSchema(service.url);
    remoteSchemas.push(retSchema);
  }
  // 用stitchSchemas替代mergeSchemas,注意参数名改为subschemas
  return stitchSchemas({
    subschemas: remoteSchemas,
  });
};

2. 修复getRemoteSchema实现(含上下文传递)

旧代码中的setContext逻辑需要迁移到buildHTTPExecutor的配置中,确保请求头能传递给远程服务:

// 导入必要模块
import { buildHTTPExecutor } from '@graphql-tools/executor-http';
import { schemaFromExecutor } from '@graphql-tools/wrap';
import fetch from 'cross-fetch'; // 环境无fetch时需安装cross-fetch

// 修改getRemoteSchema方法
getRemoteSchema: async (url) => {
  const remoteExecutor = buildHTTPExecutor({
    endpoint: url,
    // 自定义fetch逻辑,用于传递请求头
    fetch: async (uri, options) => {
      // 这里需要从当前请求上下文获取头信息,后续会和Apollo上下文关联
      const context = options?.context;
      return fetch(uri, {
        ...options,
        headers: {
          ...options.headers,
          // 替换为你需要传递的头,比如身份令牌
          Authorization: context?.req?.headers?.authorization,
          // 其他自定义请求头
        },
      });
    },
  });

  const schema = await schemaFromExecutor(remoteExecutor);
  return {
    schema,
    executor: remoteExecutor,
  };
};

3. 适配Apollo Server v4的上下文传递

确保Apollo Server的上下文能传递到远程执行器:

const start = async () => {
  const app = express();

  // 统一上下文生成逻辑
  const createContext = async ({ req, connection }) => {
    let context = {};
    if (req) {
      // 从request提取需要传递的信息,比如请求头
      context = { req };
    } else if (connection && connection.context) {
      context = connection.context;
    }
    return context;
  };

  const schema = await createSchema();

  const server = new ApolloServer({
    schema,
    introspection: true,
    // 配置Apollo Server上下文
    context: createContext,
  });

  await server.start();

  app.use(
    '/graphql',
    cors(),
    json(),
    expressMiddleware(server, {
      context: createContext, // 确保中间件使用相同上下文逻辑
    })
  );

  // 启动服务
  app.listen(4000, () => {
    console.log('Gateway running on http://localhost:4000/graphql');
  });
};

4. 补全依赖安装

确认已安装所有必要依赖:

npm install @apollo/server express graphql @graphql-tools/stitch @graphql-tools/wrap @graphql-tools/executor-http cors cross-fetch

关键说明

  • stitchSchemas是graphql-tools v9官方推荐的Schema拼接方案,原生支持subschema的执行器和上下文传递
  • 远程执行器的fetch配置是传递请求上下文的核心,必须确保当前请求的上下文能正确注入到远程调用中
  • Apollo Server v4的expressMiddleware需要显式配置上下文生成函数,确保和ApolloServer实例的上下文逻辑一致

内容的提问来源于stack exchange,提问作者Aman Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 15:02:04