Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elegant environment handling in Nest.js

I'm exploring using Nest.js for a critical application that currently has very little test-coverage. We need to make decisions based on environment flags, mostly loading additional express middleware, different loggin configuration etc. I'm using the approach to environment variables as described in the documentation, but am a bit unsure of how to elegantly (isolated, testable) handle further branching. I could handle all of this in my root module's configure hook, but feel like it'd get messy, even if I isolate it into individual methods, and there might be a better solution out there. Any help would be greatly appreciated! Thanks! ✌️

like image 408
Steven Avatar asked Jun 22 '18 15:06

Steven


1 Answers

This is how I solved when configuring the project and also an example of mongoose connection config/config.module.ts

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

@Module({
  providers: [ConfigService],
  exports: [ConfigService],
})
export class ConfigModule {}

As the .env file will not be used for production config/config.service.ts

import * as dotenv from 'dotenv';
import * as fs from 'fs';

export class ConfigService {
  MONGODB_URI: string;
  private readonly envConfig: { [key: string]: string };

  constructor() {
    if (
      process.env.NODE_ENV === 'production' ||
      process.env.NODE_ENV === 'staging'
    ) {
      this.envConfig = {
        MONGODB_URI: process.env.MONGODB_URI,
      };
    } else {
      this.envConfig = dotenv.parse(fs.readFileSync('.env'));
    }
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}

database/database.module.ts

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  imports: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {
}

database/database.providers.ts

import { ConfigModule } from '../config/config.module';
import { ConfigService } from '../config/config.service';
import { MongooseModule } from '@nestjs/mongoose';

export const databaseProviders = [
  MongooseModule.forRootAsync({
    imports: [ConfigModule],
    inject: [ConfigService],
    useFactory: async (config: ConfigService) => ({
      uri: config.get('MONGODB_URI'),
      useNewUrlParser: true,
    }),
  }),
];

like image 172
Dragos Lupei Avatar answered Sep 23 '22 14:09

Dragos Lupei