mercurius-js / mercurius

Implement GraphQL servers and gateways with Fastify

Home Page:https://mercurius.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.