Multiple endpoints graphql using Fastify and Mercurius trigger error ' The decorator 'graphql' has already been added! '
MedAzizSahli opened this issue · comments
Description
In order to have multi endpoints in a nestJs project ( /user and /system ) using fastify and mercurius. When i define two different GraphQLModule using of course different path i'm facing this error :
throw new FST_ERR_DEC_ALREADY_PRESENT(name)
^
FastifyError: The decorator 'graphql' has already been added!
Steps to Reproduce
graphql.options.ts
import { GqlOptionsFactory } from '@nestjs/graphql'
import { Injectable } from '@nestjs/common'
import { MercuriusDriverConfig } from '@nestjs/mercurius'
import { join } from 'path'
/**
* Represents the options for configuring GraphQL in the application.
*/
@Injectable()
export class GraphqlOptions implements GqlOptionsFactory {
/**
* Creates the GraphQL options.
* Using typePaths and definitions, the GraphQL schema is generated from the GraphQL schema files.
* Use autoSchemaFile instead if you want to generate the GraphQL schema from the TypeScript types.
* @returns A promise that resolves to the Mercurius driver configuration or the Mercurius driver configuration itself.
*/
createGqlOptions(): Promise<MercuriusDriverConfig> | MercuriusDriverConfig {
return {
path: '/user',
subscription: true,
graphiql: process.env.NODE_ENV === 'development',
typePaths: ['./**/user.gql'],
definitions: {
path: join(process.cwd(), 'src/user.ts'),
outputAs: 'class'
}
}
}
}
graphql.options.two.ts
import { GqlOptionsFactory } from '@nestjs/graphql'
import { Injectable } from '@nestjs/common'
import { MercuriusDriverConfig } from '@nestjs/mercurius'
import { join } from 'path'
import {SystemModule} from './system.module.ts'
/**
* Represents the options for configuring GraphQL in the application.
*/
@Injectable()
export class GraphqlOptionsTwo implements GqlOptionsFactory {
/**
* Creates the GraphQL options.
* Using typePaths and definitions, the GraphQL schema is generated from the GraphQL schema files.
* Use autoSchemaFile instead if you want to generate the GraphQL schema from the TypeScript types.
* @returns A promise that resolves to the Mercurius driver configuration or the Mercurius driver configuration itself.
*/
createGqlOptions(): Promise<MercuriusDriverConfig> | MercuriusDriverConfig {
return {
path: '/system',
include : [SystemModule]
subscription: true,
graphiql: process.env.NODE_ENV === 'development',
typePaths: ['./**/system.gql'],
definitions: {
path: join(process.cwd(), 'src/system.ts'),
outputAs: 'class'
}
}
}
}
App.Module
import { Module } from '@nestjs/common'
import { TypeOrmModule } from '@nestjs/typeorm'
import { ConfigModule, ConfigService } from '@nestjs/config'
import { AppResolver } from './app.resolver'
import { GraphQLModule } from '@nestjs/graphql'
import { GraphqlOptions } from './graphql.options'
import { GraphqlOptionsTwo } from './graphql.options.Two'
import { MercuriusDriver, MercuriusDriverConfig } from '@nestjs/mercurius'
@Module({
imports: [
ConfigModule.forRoot(),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
type: 'mysql',
host: config.get<string>('DATABASE_HOST'),
port: config.get<number>('DATABASE_PORT'),
username: config.get<string>('DATABASE_USER'),
password: config.get<string>('DATABASE_PASSWORD'),
database: config.get<string>('DATABASE_NAME'),
autoLoadEntities: true,
synchronize: false
})
}),
GraphQLModule.forRootAsync<MercuriusDriverConfig>({
driver: MercuriusDriver,
useClass: GraphqlOptions
}),
GraphQLModule.forRootAsync<MercuriusDriverConfig>({
driver: MercuriusDriver,
useClass: GraphqlOptionsTwo
})
],
providers: [AppResolver]
})
export class AppModule {}
Expected Behavior
I want to apply this feature of NestJs link.
Note the same implementation using Apollo instead of Mercurius work fine !
Thanks for reporting. We do not have the resources to support Nest.js users. Please refer to the Nest Discord channel (support) for such questions.