DEV Community

Cover image for Input Data Validation in NestJS
Geampiere Jaramillo
Geampiere Jaramillo

Posted on

1

Input Data Validation in NestJS

When building an API, one of the first lines of defense you must establish is strong input validation. This not only improves the user experience by providing clear error messages, but also protects your application from unexpected or malicious data.

I'll show you how to implement input validation in NestJS in a clean, reusable, and efficient way.


📦 What will we need?

NestJS works perfectly with two powerful libraries:

  • class-validator: to apply validation rules.
  • class-transformer: to transform incoming data into class instances.

First, let's install them:

npm install class-validator class-transformer
Enter fullscreen mode Exit fullscreen mode

📐 Step 1: Define a DTO with validation rules

A DTO (Data Transfer Object) is the cleanest and most declarative way to define what data you expect and how it should be validated.

// src/users/dto/create-user.dto.ts

import { IsString, IsEmail, IsInt, MinLength, IsNotEmpty } from 'class-validator';

export class CreateUserDto {
  @IsString()
  @IsNotEmpty()
  @MinLength(2)
  name: string;

  @IsEmail()
  email: string;

  @IsInt()
  age: number;
}
Enter fullscreen mode Exit fullscreen mode

🧱 Step 2: Use the DTO in your controller

Now, simply use it in your controller. NestJS will automatically validate the request data… but only if we enable the validation pipe (next step).

// src/users/users.controller.ts

import { Controller, Post, Body } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';

@Controller('users')
export class UsersController {
  @Post()
  createUser(@Body() dto: CreateUserDto) {
    return {
      message: `User ${dto.name} registered successfully.`,
    };
  }
}
Enter fullscreen mode Exit fullscreen mode

⚙️ Step 3: Enable the ValidationPipe globally

To automatically validate every incoming request, configure the ValidationPipe globally inside your main.ts.

// src/main.ts

import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  app.useGlobalPipes(new ValidationPipe({
    transform: true,              // Automatically transforms types
    whitelist: true,              // Strips properties not defined in the DTO
    forbidNonWhitelisted: true,   // Throws an error if unknown properties are present
  }));

  await app.listen(3000);
}
bootstrap();
Enter fullscreen mode Exit fullscreen mode

🚨 What happens if validation fails?

NestJS will automatically throw a BadRequestException. The client will receive a well-structured error response like this:

{
  "statusCode": 400,
  "message": [
    "name must be a string",
    "email must be an email",
    "age must be an integer"
  ],
  "error": "Bad Request"
}
Enter fullscreen mode Exit fullscreen mode

🧰 Bonus: Validation for query, params, and headers

You can also use DTOs to validate data inside @Query(), @param(), or @Headers():

@Get()
getUserByEmail(@Query() query: GetUserByEmailDto) {
  return this.userService.findByEmail(query.email);
}
Enter fullscreen mode Exit fullscreen mode

🏁 Conclusion

Input validation is one of the most powerful ways to keep your API robust, secure, and easy to maintain. Thanks to the integration of class-validator and class-transformer, NestJS allows us to do it in a very simple, clean, and maintainable way.

Validating data is not just a technical concern. It’s about taking care of your user experience, your application’s security, and its long-term stability.

Heroku

Amplify your impact where it matters most — building exceptional apps.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)

AWS Security LIVE! Stream

Go beyond the firewall

Watch AWS Security LIVE! to uncover how today’s cybersecurity teams secure what matters most.

Learn More

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay