Use of DTO for Validation in NestJS Application

How to handle and validate the data for a REST endpoint with the NestJS framework.

image

The purpose of this article will be to show how to handle and validate the data for a rest endpoint with the NestJS framework.

What is DTO?

DTO is the short name of Data Transfer Object. DTO is used in order to validate incoming requests.

The DTO on its own is more of a guideline for the developer and those who consume the API to know what kind of shape the request body expects to be, it doesn’t actually run any validations on its own!!!.

Why we should use DTO?

There are a few other important concepts in Nest. js: DTO: Data transfer object is an object that defines how data will be sent over the network. Interfaces: TypeScript interfaces are used for type-checking and defining the types of data that can be passed to a controller or a Nest service.

How can we use it?

Suppose that we want to create an endpoint to add a product, and we want to validate this product before entering into service. we want to validate it at the controller level. What is the way to do that with NestJS?

We need to create our DTO class 💁‍♀️, with the fields that should be validated (we should install the library class-validator to validate the data)

import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import { IsString, MaxLength } from "class-validator";
export class ProductDto {
  @ApiProperty()
  @IsString()
  @MaxLength(100)
  product_name: string;

  @IsOptional()
  @IsString()
  @MaxLength(20)
  product_code: string;
}

Now we want to add an enum field name product_type and want to validate via DTO.

import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import { IsString, MaxLength, ValidateIf, IsIn } from "class-validator";

export class ProductDto {
  @ApiProperty()
  @IsString()
  @MaxLength(100)
  product_name: string;

  @IsOptional()
  @IsString()
  @MaxLength(20)
  product_code: string;

  @ApiProperty()
  @ValidateIf((o) => o.operational_type !== "")
  @IsIn(["Goods", "Services"])
  @IsString()
  @MaxLength(8)
  product_type: string;
}

We can validate not only a single field but also can validated an array of objects with DTO in NestJS. we need to use a class transformer for this. for example we have a product array where we need to validate multiple product objects. we will just make a type of array then we will validate it.

import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import {
  IsString,
  MaxLength,
  ValidateIf,
  IsIn,
  ValidateNested,
} from "class-validator";
import { Type } from "class-transformer";

export class mainDto {
  @ApiProperty()
  @ValidateNested({ each: true })
  @Type(() => product)
  product_data: product[];
}

class product {
  @ApiProperty()
  @IsString()
  @MaxLength(100)
  product_name: string;

  @IsOptional()
  @IsString()
  @MaxLength(20)
  product_code: string;

  @ApiProperty()
  @ValidateIf((o) => o.operational_type !== "")
  @IsIn(["Goods", "Services"])
  @IsString()
  @MaxLength(8)
  product_type: string;
}

We talked enough about DTO but before that, we just need to make a global validation pipe Here is an explanation of its properties:

  • whitelist: removes all properties of a request’s body which are not in the DTO

  • transform: this property would allow us to transform properties, for instance, an integer to a string. We do not cover this today.

Some key points:

Enjoyed this article?

Share it with your network to help others discover it

Continue Learning

Discover more articles on similar topics