DEV Community

Cover image for Nest JS Class Validator & Class Transformers
Jayant
Jayant

Posted on

Nest JS Class Validator & Class Transformers

They are mostly used to validate and transform the incoming request body.

  • Class Validator : It validates incoming request against defined rules.
export class sendMessageDTO{

    @IsString();
    @IsNotEmpty()
    message:string;

    @IsMongoId();
    user:Mongoose.ObjectId;

}
Enter fullscreen mode Exit fullscreen mode

Some useful Class Validator Decorators

  • @IsString()
  • @IsNotEmpty()
  • @IsMongoId()
  • @IsNumber()
  • @IsEmail()
  • @IsBoolean()
  • @IsDate()
  • @IsArray()
  • @IsEnum()
  • @IsOptional()
  • @isin()
  • @IsInstance()
  • @IsObject()
  • @IsUrl()
  • @IsUUID()
  • @IsDateString()
  • @IsNumberString()
  • @IsAlpha()
  • @ValidatedNested()
  • @IsAlphanumeric()

Class Transformer : It converts plain JS Object into class instance.

    // This will convert req.body into sendMessageDTO instance.
    // And then we can use class validator to validate it.
    const message = plainToInstance(sendMessageDTO,req.body);
    // If we do this 
    // Then transformations happen automatically in NEST JS from object to class Instance.
    app.useGlobalPipe(new ValidationPipe({transform:true}));
Enter fullscreen mode Exit fullscreen mode
  • They are used when we have to validate Nested fields.

    class UserDTO{
        @IsString()
        @IsNotEmpty()
        name:string;
    }
    
    class SendMessageDTO{
        @IsString();
        @IsNotEmpty()
        message:string;
    
        @ValidateNested()
        user:UserDTO;
    }
    
    // BTS 
    // we got the request Body 
    // const data = {
    //     message:"Hello",
    //     user:{
    //         name:"Jayant"
    //     }
    //};
    
    // Then we convert it into the classInstance
    // const sendMessageDto = plainToInstance(SendMessageDTO,data);
    // Now our class instance, sendMessageDto will have user as simple object.
    // But we want user to be an instance of UserDTO.
    // For that we have to use class-transformer.
    // We have to use @Type() decorator.
    // @Type(() => UserDTO)
    // user:UserDTO;
    
    // Correct APPROACH :
    class SendMessageDTO{
        @IsString();
        @IsNotEmpty()
        message:string;
    
        @ValidateNested()
        @Type(()=>UserDTO)  // Imported from class-transformer
        user:UserDTO;
    }
    
  • We can also do Data Transformation inside the DTO

    class UserDTO{
        @Transform(({value})=>value.toLowerCase())
        name:string;
    }
    

Bonus

  • All this is possible due to reflect-metadata package, that allows us to attach metadata to class properties and methods. It works BTS to attach metadata to class properties and methods as decorators weren't available in JS.

  • In Controller when we do @Body sendMessage:SendMessageDTO we already got the transformed & validated, if we are using ValidationPipe.

Top comments (0)