Having a global dynamic module with a KafkaService, I encountered an issue where NestJS was unable to inject the KafkaService into my AuthenticationService.
The KafkaModule is defined as a Dynamic and Global module.
import { DynamicModule, Global, Module } from '@nestjs/common';
import { KafkaService } from './kafka.service';
import { KafkaConfig } from './kafka.types';
@Global()
@Module({})
export class KafkaModule {
static register(kafkaConfig: KafkaConfig): DynamicModule {
return {
module: KafkaModule,
global: true,
providers: [
{
provide: KafkaService,
useValue: new KafkaService(kafkaConfig),
},
],
exports: [KafkaService],
};
}
}
This module is registered in AppModule.
import { Module } from '@nestjs/common';
import { KafkaModule } from './common/kafka/kafka.module';
import { AuthenticationModule } from './modules/authentication.module';
@Module({
imports: [
KafkaModule.register({
clientId: 'abc',
brokers: ['localhost:9092'],
groupId: 'def',
}),
AuthenticationModule,
],
})
export class AppModule {}
I need to utilize KafkaService in my service.
import { Injectable } from '@nestjs/common';
import { SubscribeTo } from 'src/common/kafka/kafka.decorator';
import { KafkaService } from 'src/common/kafka/kafka.service';
import { Constant } from 'src/constant';
type LoginPayload = {
username: string;
password: string;
};
@Injectable()
export class AuthenticationService {
constructor(private kafkaService: KafkaService) {}
@SubscribeTo(Constant.TOPIC_LOGIN)
async login(payload: LoginPayload) {
console.log(this.kafkaService);
}
}
UPDATE It appears that the decorator is being called before the service injection takes place.
The decorator
@SubscribeTo(Constant.TOPIC_LOGIN)
will store the function in a variable to be executed later, but at the time of execution, the service has not been injected into the class.
As a workaround, I have decided to forego using the decorator for topic subscription and instead made modifications to the Kafka module so that the consumer does not start during module initialization.