#Get ApolloServer instance when having multiple GraphQL endpoints (schema-first)

1 messages · Page 1 of 1 (latest)

peak tulip
#

I have two graphql endpoints setup like:

@Module({
  imports: [
    GraphQLModule.forRootAsync<ApolloDriverConfig>({
      inject: [ConfigService],
      driver: ApolloDriver,
      useFactory: firstGqlProviderFactory,
    }),
    GraphQLModule.forRootAsync<ApolloDriverConfig>({
      inject: [ConfigService],
      driver: ApolloDriver,
      useFactory: secondGqlProviderFactory,
    }),
  ],
})
export class GqlModule {
}

With this I can only retrieve one of the instances using getApolloServer(app).

Are there any options to get instances separately other than running 2 nestjs apps per graphql endpoint?

raw coyote
#
GitHub

GraphQL (TypeScript) module for Nest framework (node.js) 🍷 - Issues · nestjs/graphql

GitHub

Bug Report Current behavior When adding multiple endpoints for graphql it gives following weird error (node:16316) UnhandledPromiseRejectionWarning: Error: Schema must contain uniquely named types ...

peak tulip
#

This is not my issue, I'm using schema-first approach.
I just need a way to retrieve these apollo instances separately.
As I said by using getApolloServer(app: INestApplication) I able to retrieve only instance of secondGqlProviderFactory (it seems that it gets instance of last imported GraphQLModule (see snippet in my initial message)).

raw coyote
#

ok then specify it in the title of the post or in the description, if you use the schema first mode, because it is not specified which mode you use, but how did you configure the files firstGqlProviderFactory secondGqlProviderFactory ?

peak tulip
#

Get ApolloServer instance when having multiple GraphQL endpoints (schema-first)

#

firstGqlProviderFactory and secondGqlProviderFactory look like this:

const firstGqlProviderFactory = async (config: ConfigService) => {
  const driver: Driver = await createDriver(config);

  const neoSchema = new Neo4jGraphQL({
    typeDefs: [typeDefsBase, typeDefsAdmin],
    driver,
    features: {
      populatedBy: {
        callbacks: {
          modifiedBy,
          defaultToFalse,
        },
      },
    },
  });

  const schema = await neoSchema.getSchema();
  await neoSchema.assertIndexesAndConstraints({
    options: { create: true },
  });

  return {
    playground: true,
    schema,
    path: 'neo4j',
    context: context(config),
  };
};

const secondGqlProviderFactory = async (config: ConfigService) => {
  return {
    playground: true,
    typeDefs: [typeDefsBase, typeDefsClient],
    definitions: {
      emitTypenameField: false,
      path: 'src/common/types/graphql.types.ts',
    },
    include: [ClientModule],
    context: context(config),
    path: 'admin',
  };
};
peak tulip
raw coyote
#

Seeing the "Public API" of the GraphQL module, I don't think there is the option, I send you to the link of the Api Reference for NestJS, maybe you can find something, link: https://api-references-nestjs.netlify.app/api

Unless you use createApplicationContext, but you have to try it, is to see if you can use it in this kind of case, see here: https://docs.nestjs.com/standalone-applications

peak tulip
#

Wow, thank you for provided links, it is really helpful 👍
It seems that I can make use of createApplicationContext for standalone script (since for my use case I do not require nest app listening).

const apolloServer = app.get<GraphQLModule<ApolloDriver>>(GraphQLModule).graphQlAdapter;

But I'm not sure how can I point which GraphQLModule instance I'm requesting.
Even if I split my GqlModule into two modules and trying to access GraphQLModule like this:

  app = await NestFactory.createApplicationContext(AppModule);
  console.log(
    app.select(FirstGqlModule).get<GraphQLModule>(GraphQLModule),
  );
  console.log(
    app.select(SecondGqlModule).get<GraphQLModule>(GraphQLModule),
  );

I still getting SecondGqlModule both times.

As a workaround for this I can create second AppModule and register there only single GqlModule I need access to (e.g. FirstGqlModule) and access it like app.get<GraphQLModule<ApolloDriver>>(GraphQLModule).graphQlAdapter.

raw coyote
#

Yes, let's say it could use a little more documentation on createApplicationContext, so that there are more use cases. At the moment I have not had a chance to use it.

peak tulip
#

Maybe I did smth wrong but I was not able to make this work using createApplicationContext.
app.select(FirstGqlModule).get<GraphQLModule>(GraphQLModule) does not provides access to ApolloServer instance.
Also it seems Apollo Server expects HTTP Server listening, so createApplicationContext is not suitable here, unless I'm missing smth.

For now I created minimal nest app importing required GqlModule on port different from the main nest app,
then retrieve ApolloServer instance with getApolloServer(app),
after job is done I close the app with app.close() .

This is no much better than doing everything by hand with manually instantiated ApolloServer,
unless use-case requires some NestJS modules to be instantiated, the only benefit of this approach is that it does not require ApolloServer in explicit dependencies.