NestJS暴露两个GraphQL端点报错:存在重复命名类型Province
NestJS多GraphQL端点重复类型问题解决方法
问题原因
两次调用GraphQLModule.forRoot会独立扫描并生成完全分离的Schema实例,导致同一类型(如Province)被重复注册,触发GraphQL的类型唯一性校验错误。
修复方案
核心思路是让两个端点复用同一个Schema实例,避免重复定义类型。以下是三种可行方案:
方案1:预生成共用Schema
提前构建一次Schema,两个端点直接引用该实例:
import { Module } from '@nestjs/common'; import { GraphQLModule, ApolloDriverConfig } from '@nestjs/graphql'; import { ApolloDriver } from '@nestjs/apollo'; import { buildSchema } from 'type-graphql'; import { ProvinceResolver } from './province.resolver'; // 导入所有需要的解析器 // 异步构建共用Schema const getSharedSchema = async () => buildSchema({ resolvers: [ProvinceResolver], // 包含所有共用的解析器 }); @Module({ imports: [ GraphQLModule.forRootAsync<ApolloDriverConfig>({ driver: ApolloDriver, useFactory: async () => ({ path: '/graphql', schema: await getSharedSchema(), }), }), GraphQLModule.forRootAsync<ApolloDriverConfig>({ driver: ApolloDriver, useFactory: async () => ({ path: '/graphql-public', schema: await getSharedSchema(), }), }), ], }) export class AppModule {}
方案2:复用第一个端点的Schema
通过异步工厂函数获取第一个模块生成的Schema,避免重复构建:
import { Module } from '@nestjs/common'; import { GraphQLModule, ApolloDriverConfig } from '@nestjs/graphql'; import { ApolloDriver } from '@nestjs/apollo'; @Module({ imports: [ // 第一个端点,正常生成Schema GraphQLModule.forRootAsync<ApolloDriverConfig>({ driver: ApolloDriver, useFactory: () => ({ path: '/graphql', autoSchemaFile: 'schema.gql', }), }), // 第二个端点,复用已生成的Schema GraphQLModule.forRootAsync<ApolloDriverConfig>({ driver: ApolloDriver, useFactory: async (graphQLService) => { await graphQLService.waitForSchema(); // 等待Schema生成完成 return { path: '/graphql-public', schema: graphQLService.schema, }; }, inject: [GraphQLModule], }), ], }) export class AppModule {}
方案3:共享Schema文件路径
将两个端点的autoSchemaFile指向同一文件,NestJS会自动复用已生成的Schema:
@Module({ imports: [ GraphQLModule.forRoot<ApolloDriverConfig>({ path: "/graphql", autoSchemaFile: 'shared-schema.gql', // 共用同一文件 }), GraphQLModule.forRoot<ApolloDriverConfig>({ path: "/graphql-public", autoSchemaFile: 'shared-schema.gql', // 复用该文件生成的Schema }), ], }) export class AppModule {}
注意事项
- 确保所有需要共用的解析器、类型都被包含在Schema中,避免端点功能缺失。
- 若两个端点需要区分权限(如一个公开、一个私有),可在解析器中通过Guard实现,无需拆分Schema。
内容的提问来源于stack exchange,提问作者Zain Khan
相关产品推荐
相关产品推荐

