6

My app instance depends on configuration : serviceName in that case

const serviceName = 'authentication-service'
const servicePrefix = `api/${serviceName}`;
const swaggerPrefix = 'swagger';
...
const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter({
      requestIdLogLabel: serviceName,
      logger: true,
      ...
    }),
    {
      // logger: ['log']
      logger: process.env.DEV === '1' ? ['log', 'debug', 'error', 'verbose', 'warn'] : ['error', 'warn'],
    });

NestJs documentation uses app instance to get the configService singleton :

const configService = app.get(ConfigService);
const port = configService.get('PORT');

Is there any way to get the configService instance before instantiating my app?

jarjar
  • 359
  • 4
  • 10

4 Answers4

4

Nope. You could call dotenv's config() method yourself and populate process.env if you really need to, but that's about it. Technically, if you really wannted you could create a NestFactory.createApplicationContext() call and get the ConfigService from there, close the context and start up the application with the standard NestFactory.create, but that will end up doing the DI resolution twice, which would be a pretty slow startup

Jay McDoniel
  • 57,339
  • 7
  • 135
  • 147
  • 2
    Thank's for your quick reply! It seems that NestJs has lost something here. A good framework simplifies things and tries to cover most use cases. One of these standard use case is to get configuration and use it to bootstrap the application (this is what Spring framework does). They do it in reverse here! – jarjar Mar 12 '21 at 20:07
  • I agree, I need to create an MQTT microservice using the ConfigService to get the url. I can't seem to set the URL after creating the microservice, but i can't get the config before creating the microservice – Rusty Rob Sep 19 '22 at 21:34
2

I had a similar need (for the Mikro-ORM configuration file). What I did is to create a new instance of ConfigService:

import {ConfigService} from '@nestjs/config'
const configService = new ConfigService()

Then I could use configService to get the port number:

configService.get<number>('PSQL_PORT', 5432)

Update

@TheoCerutti commented yesterday that this does not work. It actually does work; I have tested this with Nest 10 on Linux.

Here is a reproduction (tested using BASH).

# Define the location where the test repository should be located
root_folder="$HOME"

# Generate a new Nest app
nest new -p pnpm --strict "$root_folder/nest-config-service-in-main"

# Change to the repository folder
cd "$root_folder/nest-config-service-in-main"

# Update the `main.ts` file contents
# Note: I have removed all the unrelated commands from that file,
#       as bootstrapping the Nest app is actually not necessary to make this work.
cat << EOF > "$root_folder/nest-config-service-in-main/src/main.ts"
import {ConfigService} from '@nestjs/config'

const configService = new ConfigService()
console.log(configService.get<number>('PSQL_PORT', 5432))
EOF

# Testing
pnpm start  # Output: `5432`
PSQL_PORT=2345 pnpm start  # Output: `2345`
tukusejssirs
  • 564
  • 1
  • 7
  • 29
1

What you need to do is to create a dummy app instance before the actual app.

  const configApp = await NestFactory.create(AppModule);
  let configService = configApp.get(ConfigService);

  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter({
      requestIdLogLabel: serviceName,
      logger: true,
      ...
    }),
    {
      // logger: ['log']
      logger: process.env.DEV === '1' ? ['log', 'debug', 'error', 'verbose', 'warn'] : ['error', 'warn'],
    });
    //...
n3n3
  • 288
  • 1
  • 7
0

I am using custom configuration files as defined in https://docs.nestjs.com/techniques/configuration#custom-configuration-files

and with that I can use just use the following to get access to the config already in a js object.

async function bootstrap() {
  const conf = configuration();
  ...

I initiall tried the solution from tukusejssirs which also worked but it would not map the env entries to js object yet so I came up with this one.

Comments appreciated as it feels a bit weird...

TomFree
  • 1,091
  • 3
  • 17
  • 31