Robust Environment Variable Validation in NestJS Applications
Tags: nestjs, environmentvariables, validation, configuration
Published: 2023-05-05 13:21:27

## Introduction:

In this article, we will explore how to validate environment variables in a NestJS application. Validating environment variables is crucial for ensuring that your application is running with the correct configuration and helps prevent runtime errors due to misconfigured or missing variables. We will use the `@nestjs/config`, `class-transformer`, and `class-validator` packages to achieve this.

**Step 1: Install Dependencies**
First, let's install the required dependencies:

```bash
npm i --save @nestjs/config class-transformer class-validator
```

**Step 2: Create a Validation File**
Create a new file named `src/env.validation.ts`. In this file, we will define the environment variables we want to validate, such as database configuration variables.

Here's an example of the `env.validation.ts` file:

```typescript
import { plainToInstance } from 'class-transformer';
import { IsNumber, IsString, validateSync } from 'class-validator';

class EnvironmentVariables {
    @IsString()
    DATABASE_HOST: string;

    @IsNumber()
    DATABASE_PORT: number;

    @IsString()
    DATABASE_USERNAME: string;

    @IsString()
    DATABASE_PASSWORD: string;

    @IsString()
    DATABASE_NAME: string;
}

export function validate(config: Record<string, unknown>) {
    const validatedConfig = plainToInstance(
        EnvironmentVariables,
        config,
        { enableImplicitConversion: true },
    );
    const errors = validateSync(validatedConfig, { skipMissingProperties: false });

    if (errors.length > 0) {
        throw new Error(errors.toString());
    }
    return validatedConfig;
}
```

In this file, we define a class `EnvironmentVariables` with the required properties and their validation decorators. The `validate` function takes a configuration object, converts it to an instance of `EnvironmentVariables`, and validates it using `validateSync`. If there are any validation errors, an exception is thrown.

**Step 3: Load ConfigModule in AppModule**
Next, we need to load the `ConfigModule` in our `app.module.ts` file and provide the `validate` function we created earlier:

```typescript
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { validate } from './env.validation';

@Module({
  imports: [
    ConfigModule.forRoot({
      validate,
      isGlobal: true
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule { }
```

**Step 4: Create a .env File**
Create a `.env` file in the root of your project with the required environment variables. For example:

```
DATABASE_HOST=postgres
DATABASE_PORT=5432
DATABASE_USERNAME=postgres
DATABASE_PASSWORD=dev-secret
DATABASE_NAME=postgres
```

Now, when you run your NestJS application, it should start successfully if all environment variables are correctly configured.


![Show successful message](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x8ht69z4lmyvhsvxzpyl.png)

However, if any environment variable is missing or has an incorrect value, an exception will be thrown, and the application will not start.

For example, if we comment out the `DATABASE_NAME` variable in the `.env` file and restart the application:


![Show an error message when Nestjs start](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sqjozj9jzduoy7qw14wt.png)

## Conclusion:
Validating environment variables in your NestJS application is an effective way to ensure that your application is running with the correct configuration and to catch errors early in the development process. By using the `@nestjs/config`, `class-transformer`, and `class-validator` packages, you can easily implement robust validation for your environment variables.