I'm facing an issue using NestJS and its ConfigService that I canno't find any solution and also I'm not sure if I'm trying something that it is not built for.
I have a global config service that loads the configuration with an external REST API. Until here there is no problem.
But now I trying to reload this config, because this remote config could change eventually. Currently I'm doing polling service that check when this config has changed and then update that global config.
Here I put an dummy example that how I'm doing
app.module.ts
@Module({
imports: [
ConfigModule.forRoot({
load: [config],
ignoreEnvFile: false,
isGlobal: true,
cache: false,
}),
SomeModuleUsesConfig1,
SomeModuleUsesConfig2,
],
controllers: [AppController],
providers: [],
})
export class AppModule {}
config.ts
let InMemoryConfig = { config: null }
const getRemoteConfig = async () => {
//Some logic to retrieve the remote config
const remoteConfig = await axios(...)
return remoteConfig; //It will be something like { config: { ... } }
};
const loadConfig = async () => {
let { config } = getRemoteConfig();
InMemoryConfig.config = config;
return InMemoryConfig;
};
//I tested calling this interval to check the updates
setInterval(() => {
loadConfig();
})
//Here I use the await to check if the config is loaded on bootstrap but I guess it could be
//okey just with return loadConfig();
export default async () => {
let configLoaded = await loadConfig();
return configLoaded.config;
};
And finally I'm using the config service on the "SomeModuleUseConfig1 and 2" in this way
SomeModuleUsesConfig1.module.ts
import { Module } from '@nestjs/common';
import { SomeModuleUsesConfig1Service } from './SomeModuleUsesConfig1.service';
import { SomeModuleUsesConfig1Controller } from './SomeModuleUsesConfig1.controller';
@Module({
controllers: [SomeModuleUsesConfig1],
providers: [SomeModuleUsesConfig1],
})
export class SomeModuleUsesConfig1 {}
and finally the service that uses that
SomeModuleUsesConfig1.service.ts
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class SomeModuleUsesConfig1 {
constructor(private configService: ConfigService) {}
//This service is called by a controller
getItem() {
const dbConfig = this.configService.get<string>('dbData');
return dbCOnfig;
}
}
I expect this "getItem" function return the configuration of the global ConfigService and it does, but it never updates if I change the ConfigService values anywhere except this service. So I suppose the ConfigService is not being loaded as a singleton and this is only an instance for this service. But If I'm not misunderstanding the "ConfigModule.forRoot" configuration means that the ConfigModule (and the service exported by this) becomes Global to the entire app meanwhile I not import explicitly the ConfigService on each other Services
Anyone knows what I'm doing wrong? Or it is just this ConfigModule is not built to do this runtime updates?
Thank you in advance
I've tried to update the config overriding values assuming that ConfigService is a Singleton with something like:
let config = ConfigService.get('config')
// And then updating al properties iterating over them
Also overriding the service doing
this.configService = new ConfigService(<remoteConfig>)
And finally I expect that changing these values in the ConfigService anywhere where I get this props will be updated with the latest values
EDIT 1
Also teste returning the full config object that I want to mutate but it was the same result