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

基于NestJS GraphQL模块的Apollo Gateway如何保存Schema文件?

解决NestJS Apollo Gateway生成并保存组合Schema的方案

核心问题原因

IntrospectAndCompose是异步拉取并组合子图Schema的模式,onModuleInit钩子执行时,Gateway还未完成子图的 introspection 和Schema组合流程,因此GraphQLSchemaHost无法获取到已生成的最终Schema。

可行方案

方案一:监听Apollo Gateway的onSchemaChange事件

Apollo Gateway内置了onSchemaChange回调,当组合后的Schema完成更新时会自动触发,可在此回调中直接将Schema写入文件。

代码示例:

import { Module } from '@nestjs/common';
import { GraphQLGatewayModule, IntrospectAndCompose } from '@nestjs/graphql';
import { writeFileSync } from 'fs';
import { printSchema } from 'graphql';

@Module({
  imports: [
    GraphQLGatewayModule.forRootAsync({
      useFactory: () => ({
        server: {
          cors: true, // 根据项目需求配置网关服务参数
        },
        gateway: {
          supergraphSdl: new IntrospectAndCompose({
            subgraphs: [
              { name: 'users', url: 'http://localhost:3001/graphql' },
              // 依次添加所有子图配置
            ],
            onSchemaChange: ({ schema }) => {
              const schemaContent = printSchema(schema);
              writeFileSync('./schema.gql', schemaContent);
              console.log('组合Schema已保存到schema.gql');
            },
          }),
        },
      }),
    }),
  ],
})
export class AppModule {}

方案二:在onApplicationBootstrap中等待Schema就绪

onApplicationBootstrap钩子会在所有模块初始化完成后执行,此时可注入Gateway实例,手动等待Schema组合完成后再保存。

代码示例:

import { Injectable, OnApplicationBootstrap, Inject } from '@nestjs/common';
import { Gateway } from '@apollo/gateway';
import { writeFileSync } from 'fs';
import { printSchema } from 'graphql';
import { GATEWAY_INSTANCE } from '@nestjs/graphql';

@Injectable()
export class SchemaSaver implements OnApplicationBootstrap {
  constructor(@Inject(GATEWAY_INSTANCE) private readonly gateway: Gateway) {}

  async onApplicationBootstrap() {
    // 等待Gateway完成子图 introspection 和Schema组合
    await this.gateway.load();
    final schema = await this.gateway.schema();
    const schemaContent = printSchema(schema);
    writeFileSync('./schema.gql', schemaContent);
    console.log('组合Schema已成功保存');
  }
}

将SchemaSaver加入对应模块的providers数组即可生效。

方案三:编写独立脚本手动生成Schema

若不需要在应用启动时自动生成,可编写独立脚本,手动触发子图 introspection 并组合保存Schema:

import { IntrospectAndCompose } from '@apollo/gateway';
import { writeFileSync } from 'fs';
import { printSchema } from 'graphql';

async function generateSupergraphSchema() {
  const composer = new IntrospectAndCompose({
    subgraphs: [
      { name: 'users', url: 'http://localhost:3001/graphql' },
      // 配置所有子图地址
    ],
  });

  const schema = await composer.getSchema();
  const schemaContent = printSchema(schema);
  writeFileSync('./schema.gql', schemaContent);
  console.log('Supergraph Schema已生成');
}

generateSupergraphSchema().catch(err => console.error('生成失败:', err));

运行脚本前需确保所有子图服务处于启动状态。

注意事项

  • 所有子图服务必须在Gateway启动或脚本运行时保持可用,否则introspection流程会失败。
  • 方案一可自动监听子图Schema更新并重新保存,方案二需重启应用才能更新保存的Schema,方案三需重新运行脚本。
  • 可根据项目结构调整Schema保存路径,比如../client/schema.gql,方便客户端代码生成工具直接读取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:22:03