在@nestjs/graphql中无法使用Apollo Gateway的transformSchema与自定义指令
NestJS Apollo Gateway中transformSchema未触发及联邦架构自定义指令生效问题
问题概述
采用代码优先的NestJS应用中,配置Apollo Gateway时遇到以下问题:
transformSchema函数完全未触发,即使添加日志也无输出,导致子图定义的@public自定义指令无法在网关层生效,无法实现基于指令的鉴权跳过逻辑。- 网关配置可添加任意无效属性(如
abc: true)而无报错,说明@nestjs/graphql对联邦模式下的配置未做校验。
复现场景
- 基于
@nestjs/graphql和@apollo/gateway搭建联邦GraphQL架构,网关配置中添加transformSchema和自定义指令转换器。 - 启动子图与网关,执行查询后,网关日志无
transformSchema相关输出,自定义指令逻辑不生效。 - 向网关配置添加任意键值对,服务启动无报错提示。
原因分析
@nestjs/graphql在封装Apollo Gateway时,未将transformSchema等schema转换相关配置传递给底层的Apollo Gateway实例,导致配置被忽略。同时,联邦模式下的配置校验逻辑缺失,允许无效属性存在。
解决方案
1. 手动创建Apollo Gateway实例
绕过NestJS封装的配置层,直接初始化Apollo Gateway实例并传入GraphQLModule,确保transformSchema被正确调用:
// app.module.ts import { Module } from '@nestjs/common'; import { GraphQLModule } from '@nestjs/graphql'; import { ApolloGatewayDriver, ApolloGatewayDriverConfig } from '@nestjs/apollo'; import { ApolloGateway, IntrospectAndCompose } from '@apollo/gateway'; import { publicDirectiveTransformer } from './directives/public.directive'; // 手动创建Apollo Gateway实例 const gateway = new ApolloGateway({ supergraphSdl: new IntrospectAndCompose({ subgraphs: [ { name: 'platform', url: 'http://localhost:3001/graphql' }, // 其他子图配置 ], }), // 直接在原生配置中添加transformSchema transformSchema: (schema) => { console.log('执行Schema转换'); return publicDirectiveTransformer(schema); }, }); @Module({ imports: [ GraphQLModule.forRoot<ApolloGatewayDriverConfig>({ driver: ApolloGatewayDriver, // 传入已初始化的gateway实例 gateway, playground: true, }), ], }) export class AppModule {}
2. 手动校验配置(可选)
针对配置无校验的问题,可使用TypeScript类型约束或Zod等工具手动校验网关配置,避免无效属性:
import { z } from 'zod'; // 定义网关配置的校验schema const GatewayConfigSchema = z.object({ supergraphSdl: z.any(), transformSchema: z.function().optional(), // 其他允许的配置项 }); // 校验配置 const validatedConfig = GatewayConfigSchema.parse({ supergraphSdl: new IntrospectAndCompose({ /* ... */ }), transformSchema: /* ... */, }); const gateway = new ApolloGateway(validatedConfig);
验证步骤
- 按照上述代码修改网关的
app.module.ts。 - 启动子图服务,再启动网关服务。
- 查看网关启动日志,确认出现「执行Schema转换」的输出。
- 执行带有
@public指令的查询,验证鉴权逻辑是否被正确跳过。
补充说明
该问题已提交至NestJS GraphQL官方仓库,后续版本可能会修复封装层的配置传递与校验问题。当前方案为临时 workaround,可满足基于子图指令的鉴权控制需求。
内容的提问来源于stack exchange,提问作者Ahmad Salman Khan
相关产品推荐
相关产品推荐

