11

I'am creating a microservice in NestJS. Now I want to use RabbitMQ to send messages to another service.

My question is: is it possible to import the RabbitmqModule based on a .env variable? Such as: USE_BROKER=false. If this variable is false, than don't import the module?

RabbitMQ is imported in the GraphQLModule below.

@Module({
  imports: [
    GraphQLFederationModule.forRoot({
      autoSchemaFile: true,
      context: ({ req }) => ({ req }),
    }),
    DatabaseModule,
    AuthModule,
    RabbitmqModule,
  ],
  providers: [UserResolver, FamilyResolver, AuthResolver],
})
export class GraphQLModule {}

RabbitmqModule:

import { Global, Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { RabbitMQModule } from '@golevelup/nestjs-rabbitmq';
import { UserProducer } from './producers/user.producer';

@Global()
@Module({
  imports: [
    RabbitMQModule.forRootAsync(RabbitMQModule, {
      useFactory: async (config: ConfigService) => ({
        exchanges: [
          {
            name: config.get('rabbitMQ.exchange'),
            type: config.get('rabbitMQ.exchangeType'),
          },
        ],
        uri: config.get('rabbitMQ.url'),
        connectionInitOptions: { wait: false },
      }),
      inject: [ConfigService],
    }),
  ],
  providers: [UserProducer],
  exports: [UserProducer],
})
export class RabbitmqModule {}
GabLeRoux
  • 16,715
  • 16
  • 63
  • 81
joey
  • 227
  • 3
  • 18

2 Answers2

10

I think the recommended way to do so is to use the DynamicModule feature from NestJS.

It is explained here: https://docs.nestjs.com/fundamentals/dynamic-modules

Simply check your environment variable in the register function and return your Module object. Something like:

@Module({})
export class GraphQLModule {
  static register(): DynamicModule {
    const imports = [
      GraphQLFederationModule.forRoot({
        autoSchemaFile: true,
        context: ({ req }) => ({ req }),
      }),
      DatabaseModule,
      AuthModule]
    if (process.env.USE_BROKER) {
      imports.push(RabbitmqModule)
    }
    return {
      imports,
      providers: [UserResolver, FamilyResolver, AuthResolver],
    };
  }
}
Community
  • 1
  • 1
nero408
  • 128
  • 7
  • 4
    But what if we want to make use of ConfigService to determine whether the RabbitmqModule should be loaded or not? Instead of having process.env hardcoded – Manish Jangir Sep 29 '21 at 15:09
  • 1
    Any answer to above question? How do we implement this solution using ConfigService instead of process.env? – jm18457 Oct 09 '21 at 19:29
  • To use ConfigService in register method, see https://stackoverflow.com/a/54310397/901597 – Joe Bowbeer Feb 07 '22 at 06:45
7

Well I tried a simple workaround, in a small nest project, and it worked just fine. Check it out:

const mymodules = [TypeOrmModule.forRoot(typeOrmConfig), UsersModule];
if (config.get('importModule')) {
    mymodules.push(PoopModule);
}
@Module({
    imports: mymodules,
    controllers: [AppController],
    providers: [AppService],
})
export class AppModule {}

I created an "importModule" in my env/config, and tested it with true and false. If true my Poop module gets deployed, else it doesn't deploy, only the other modules.

Can you try the same in your project?

GabLeRoux
  • 16,715
  • 16
  • 63
  • 81
Bruno Lamps
  • 544
  • 6
  • 27
  • Yes, calculating the imports array based on a condition is the easiest way to accomplish this functionality – Jesse Carter Dec 19 '20 at 02:45
  • Where did you define config in this example? – jm18457 Oct 07 '21 at 13:47
  • @jm18457 I don't have the sample project with me anymore, but I guess you can just use `dotenv` or similar library. The one described in my code is https://www.npmjs.com/package/config. You can just install it, create a `/config/default.json` in your project, and store values in there (I'm using `/config/default.yml` in a different project and it also seems to work fine). I import this lib using the syntax `import * as config from 'config';` – Bruno Lamps Oct 07 '21 at 13:56
  • Ok, thx. I thought you were using the config service from Nest.js. I want to read .env variables from the configService. – jm18457 Oct 09 '21 at 19:29
  • I did try to use sometimes, but usually I give up on this module and install dotenv instead, sry =] – Bruno Lamps Oct 10 '21 at 20:27