Skip to content

Configuration System

Our configuration system is designed to seamlessly integrate with NestJS ConfigModule, providing an easy and efficient way to manage app settings and validate environment variables. By following a standardized approach for config initialization, we ensure consistency and maintainability across your application. All configuration files are imported from /src/config/index.ts and loaded globally, making it simple to access and manage settings throughout your app.

How to integrate the Configuration System with NestJS ConfigModule

Our configuration system utilizes the ConfigModule from @nestjs/config for managing application settings. We have established a standard approach for initializing configurations and validating environment variables.

All configurations are imported from /src/config/index.ts.

Here's an example of how to set up the configuration system:

ts
// src/app.module.ts

import { ConfigModule } from '@nestjs/config';
import * as configs from './config';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      load: Object.values(configs),
    }),
  ],
})
export class AppModule {}

By following this structure, you can easily manage configurations in a consistent and organized manner. The load property accepts an array of configuration objects, which can be imported directly from the src/config directory. This ensures that the configurations are applied globally throughout the application.

How to create own config

To create your own config, follow these steps:

  1. Start by creating a new configuration file, such as app.config.ts, inside the src/config directory.

Utilize the class-validator library to define and validate the environment variables for your new config. Create a class representing your environment variables, and use decorators like @IsNumber, and @IsString to describe and validate the variable types.

For example, here's how to create an AppConfigEnvironmentVariables class with PORT and APP_HOST variables:

ts
import { Type } from 'class-transformer';
import { IsNumber, IsString } from 'class-validator';

export class AppConfigEnvironmentVariables {
  /**
   * Application port
   * @example
   * ```yaml
   * PORT: 3000
   * ```
   */
  @Type(() => Number)
  @IsNumber()
  PORT = 3000;

  /**
   * Application environment. Can be 'local', 'development', 'stage', 'production'
   * @example
   * ```yaml
   * APP_ENV: 'local'
   * ```
   */
  @IsEnum(AppEnv)
  APP_ENV!: AppEnv;

  /**
   * Application host
   * @example
   * ```yaml
   * APP_HOST: 'https://app-api.example.com'
   * # or
   * APP_HOST: 'http://localhost:3000'
   * ```
   */
  @IsString()
  APP_HOST!: string;
}
  1. After this, you need to use the registerAs function from @nestjs/config and validateEnv from @deeepvision/nest-kit to create a config and validate environment variables on-the-fly.
ts
import { validateEnv } from '@deeepvision/nest-kit';
import { registerAs } from '@nestjs/config';
import { IsString } from 'class-validator';

class AppConfigEnvironmentVariables {
  // ...
}

export const AppConfig = registerAs('AppConfig', () => {
  const env = validateEnv(AppConfigEnvironmentVariables);

  return {
    env: env.APP_ENV,
    name: 'Jetstream',
    shortname: 'js',
    port: env.PORT,
    host: env.APP_HOST,
  };
});

In this example, the validateEnv function is used to validate the environment variables defined in the AppConfigEnvironmentVariables class. The registerAs function creates a new config object with the validated environment variables, and assigns it to the AppConfig constant. This ensures that your application has a properly configured and validated set of environment variables.

validatedEnv is a typed object that contains the validated environment variables from the AppConfigEnvironmentVariables class, ensuring type safety and adherence to the defined constraints.

  1. Export the AppConfig in the config/index.ts file, making it convenient to import and use in other parts of your application. Update the config/index.ts file to export the AppConfig:
ts
// src/config/index.ts

import { AppEnv } from '@deeepvision/nest-kit';
import { useDotEnv } from '@deeepvision/dotenv-yaml';

/* Inject environment variables from .env.yaml */
if (process.env.APP_ENV === AppEnv.LOCAL) {
  useDotEnv();
}

export * from './app.config';
  1. Now you can import the AppConfig directly from the ./config path:
ts
import { AppConfig } from './config';
  1. To inject the AppConfig into your services or other NestJS components, you can use the @Inject decorator provided by NestJS and the ConfigType.
ts
@Injectable()
export class MyService {
  constructor(
    @Inject(AppConfig.KEY) private appConfig: ConfigType<typeof AppConfig>,
  ) {}

  someMethod() {
    const appName = this.appConfig.name;
    const appHost = this.appConfig.host;
    const appPort = this.appConfig.port;
    
    console.log(`App Name: ${appName}`);
    console.log(`App Host: ${appHost}`);
    console.log(`App Port: ${appPort}`);
  }
}

In this example, we inject the AppConfig directly into the MyService class, making it easier to access the configuration values. You can then access the properties like name, host, and port directly from the appConfig.

Key Features:

Typed environment variables: AppConfig uses class-validator to define and validate environment variables, ensuring that the application receives the correct types and values.

Easy injection: AppConfig can be easily injected into services and controllers using the @Inject() decorator, giving developers access to configuration values throughout their applications.

Fallback values: AppConfig provides default values for certain environment variables, ensuring that the application can run smoothly even if some variables are not explicitly set.

Created by DeepVision Software.