Fullstack NestJS

Application Configuration


The Goal

Applications often operate in various environments, each requiring different configuration settings. For instance, the local environment may rely on specific database credentials that are only valid for the local database instance. On the other hand, the production environment would utilize a separate set of database credentials. To handle these changing configuration variables, it is considered a best practice to store them in the environment.

In Node.js, externally defined environment variables can be accessed through the process.env global object. One possible solution to manage multiple environments is to set the environment variables separately in each environment. However, this approach can become cumbersome, especially in development and testing environments where these values often need to be easily mocked or modified.

To address this challenge, Node.js applications commonly use .env files, which contain key-value pairs representing the configuration for each environment. By swapping in the appropriate .env file, an application can be run in different environments effortlessly.

In Nest, a recommended approach is to create a ConfigModule that exposes a ConfigService responsible for loading the relevant .env file. While it is possible to implement such a module from scratch, Nest provides the convenient @nestjs/config package out-of-the-box, which we will explore in this chapter.

The Code

We need to install the config package.

npm i --save @nestjs/config

We will create a .env file in the root and populate with a fake API key.

SUPER_SECRET_API_KEY=f50845f3-c8f9-42bd-9870-8aa93a2377ae

Then we will inject the ConfigModule into our AppModule with the isGlobal flag set to true.

import { Module } from '@nestjs/common';
import { FeaturesModule } from './features/features.module';
import { DatabaseModule } from './database/database.module';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    FeaturesModule,
    DatabaseModule,
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

Then we can pull the API key into our application using the ConfigService and calling the get method on it.

//...
import { ConfigService } from '@nestjs/config';

@Injectable()
export class FeaturesService {
  constructor(
    @Inject('FEATURE_REPOSITORY')
    private featuresRepository: Repository<Feature>,
    private configService: ConfigService
  ) {
    // FOR DEMONSTRATION PURPOSES ONLY
    const API_KEY = this.configService.get<string>('SUPER_SECRET_API_KEY');
    console.log('👉 THE API_KEY IS: ', API_KEY);
  }

  //...
}
< Nest Home