DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • How To Build Web Service Using Spring Boot 2.x
  • How to Do API Testing?
  • TDD Typescript NestJS API Layers with Jest Part 1: Controller Unit Test
  • Scalable Support Request Analysis Using Embeddings, HDBSCAN, and Tiny LLMs

Trending

  • Stop Debugging Glue Jobs Manually: Building an Agentic Observability Layer for Data Pipelines
  • Observability for Agents and Workflows: Tracing Prompts, Tool Calls, and Business Outcomes End-to-End
  • When One MVP Is Really Four Systems: A Better Way to Plan Multi-Role Apps
  • Build a GitHub Slack Bot With AWS Bedrock and MCP, Part 1
  1. DZone
  2. Coding
  3. JavaScript
  4. Using the In-Built NestJS ValidationPipe

Using the In-Built NestJS ValidationPipe

Let's get to validating your data.

By 
Saurabh Dashora user avatar
Saurabh Dashora
DZone Core CORE ·
Sep. 19, 21 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
10.1K Views

Join the DZone community and get the full member experience.

Join For Free

The in-built NestJS ValidationPipe is a great way to handle validations in an application.

Validations are an extremely important aspect of any production-level application. Often, developers have to write large amounts of code to handle even basic validations. This is largely counter-productive.

With NestJS ValidationPipe, handling several validations becomes much easier. In this post, we look at how to use the in-built ValidationPipe.

So let’s begin.

1 – NestJS ValidationPipe

ValidationPipe is similar to other in-built pipes available with NestJS. In case you want to know more about the basics of NestJS Pipes, please refer to this post.

Apart from ValidationPipe, other pipes such as ParseIntPipe, ParseBoolPipe, ParseUUIDPipe can also be used for validation purposes. However, ValidationPipe makes use of the powerful class-validator package. Due to this, we can set up validations in a declarative manner.

To begin with ValidationPipe, we need to first install the class-validator package. Below is the command.

Shell
 
npm i --save class-validator class-transformer


You can read more about class-validator from its official site.

2 – Setting up Auto Validation

We will start by setting up auto validation using ValidationPipe.

As a first step, we bootstrap the ValidationPipe in the bootstrap function available in main.ts. See the example below :

TypeScript
 
main.tsimport { 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())
  await app.listen(3000);
}
bootstrap();


Here, we call the useGlobalPipes() method. Basically, we pass it as an instance of the ValidationPipe class. Notice here that ValidationPipe is part of the @nestjs/common package.

To test our pipe, let’s create a simple controller as below.

TypeScript
 
user.controller.tsimport { Body, Controller, Post } from "@nestjs/common";
import { CreateUserModel } from "./create-user-model";

@Controller()
export class UserController {

    @Post("/user")
    create(@Body() createUserModel: CreateUserModel) {
        console.log("New User Created");
    }

}


As you can see, it is a simple controller. It basically accepts a model to create a new user. Let’s see how the model looks like.

TypeScript
 
create-user-model.tsimport { IsEmail, IsNotEmpty } from "class-validator";

export class CreateUserModel {
    @IsEmail()
    email: string;

    @IsNotEmpty()
    password: string;
}


Notice the decorators @IsEmail() and @IsNotEmpty(). These decorators basically represent the validation rules for particular fields. In other words, the email field should contain a valid email id. And the password field should not be empty. These decorators are part of the class-validator package.

For example, if an incoming request with an invalid email hits our endpoint, the response would be as below:

JSON
 
{
"statusCode": 400,
"message": [
  "email must be an email"
],
"error": "Bad Request"
}


3 – ValidationPipe with Request Parameters

We can also use ValidationPipe with other request parameters such as a path parameter.

Check out the below controller.

TypeScript
 
@Get("/user/:id")
get(@Param() params: SearchParams) {
    console.log("User fetched");
}


Here, we have a path variable id. SearchParams is simply a DTO class similar to our previous example.

TypeScript
 
import { IsNumberString } from "class-validator";

export class SearchParams {
    @IsNumberString()
    id: number;
}


The decorator @IsNumberString ensures that only numbers are accepted. If we call the endpoint /user/xyz, we get the following error.

JSON
 
{
"statusCode": 400,
"message": [
  "id must be a number string"
],
"error": "Bad Request"
}


4 – Disabling Error Details in ValidationPipe

Usually, it is a good practice to make your application error messages more informative. However, for some production requirements, detailed error messages are not needed.

In such cases, we can disable the error messages. Basically, we have to tweak the configuration of the ValidationPipe object.

See the following example:

TypeScript
 
main.tsimport { 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({
    disableErrorMessages: true,
  }))
  await app.listen(3000);
}
bootstrap();


5 – Stripping or Whitelisting Properties

We can also strip unwanted properties from incoming requests. In other words, we can whitelist certain properties.

See the following DTO class.

TypeScript
 
create-user-model.tsimport { IsEmail, IsNotEmpty } from "class-validator";

export class CreateUserModel {
    @IsEmail()
    email: string;

    @IsNotEmpty()
    password: string;

    address: string;
}


Here, the address field is not annotated. Basically, we have not whitelisted this property. We want this to be stripped from the payload even if the incoming request contains the same.

To achieve that, we can simply add another configuration parameter in ValidationPipe as below:

TypeScript
 
main.tsimport { 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({
    disableErrorMessages: true,
    whitelist: true
  }))
  await app.listen(3000);
}
bootstrap();


See the whitelist: true property in the configuration object. In this case, the request will be processed and the non-whitelisted properties will be stripped off.

Alternatively, we can also make the request fail. Doing so is, again, a simple matter of configuration. See the following example.

TypeScript
 
main.tsimport { 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({
    whitelist: true,
    forbidNonWhitelisted: true
  }))
  await app.listen(3000);
}
bootstrap();


Now, if we call the end-point with extra property, we get the below error.

JSON
 
{
"statusCode": 400,
"message": [
  "property address should not exist",
  "email must be an email"
],
"error": "Bad Request"
}


The first message is telling us to remove the address property from the input payload.

Conclusion

With this, we have a detailed view of how to use the in-built NestJS ValidationPipe.

In another post, we will look at how to transform a request payload using NestJS Mapped Types.

If you have any comments or queries, please mention them in the comment section below.

TypeScript Requests Property (programming)

Published at DZone with permission of Saurabh Dashora. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • How To Build Web Service Using Spring Boot 2.x
  • How to Do API Testing?
  • TDD Typescript NestJS API Layers with Jest Part 1: Controller Unit Test
  • Scalable Support Request Analysis Using Embeddings, HDBSCAN, and Tiny LLMs

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook