Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding validation for required params in nestjs using class-validator

Using class-validator, validation pipes I would like to mark some fields as required. I tried using @IsNotEmpty method. It throws a 400 error when the input is empty. But i need to throw an error if input is missing as well.

DTO: Address Object with fields address1 and address 2. I would like to have address1 as required and address2 as optional

import {IsString, IsInt, IsNotEmpty } from 'class-validator';
import {ApiModelProperty} from '@nestjs/swagger';
export class Address {

    @ApiModelProperty({description: 'Address Line 1', required : true})
    @IsString()
    @IsNotEmpty()
    required : true
    address1: string;

    @ApiModelProperty({description: 'Address Line 2', required :false})
    @IsString()
    address2?: string;
}
// App.js: Application file where validation pipes are defined.
async function bootstrap() {
    const expressServer = express();

    const app = await NestFactory.create(AppModule, expressServer, {bodyParser: true});
    app.use(bodyParser.json({limit: 6851000}));

    app.useGlobalInterceptors(new UnhandledExceptionInterceptor());

    app.useGlobalFilters(new HttpErrorsExceptionFilter());

    app.useGlobalFilters(new UnhandledExceptionFilter(newLogger('UnhandledExceptionFilter')));

    app.useGlobalPipes(new ValidationPipe({skipMissingProperties: true}));

    app.useGlobalPipes(new ValidationPipe({forbidNonWhitelisted :true, whitelist:true, transform:true}));

}

Sample Input: Sample input with both the fields.

{  
  "shippingAddress": {
    "address1":,
    "address2": null 
  }
}

In this case this provides a 400 as expected, But I also need an error when input is like below missing one of required fields,

{  
  "shippingAddress": {
    "address2": null
   } 
}
like image 957
arke Avatar asked Dec 06 '25 14:12

arke


1 Answers

This is the standard functionality of class-validator so long as you do not add the @IsOptional() decorator. I'm adding the pipes directly to the controller but the idea is the same. See my class and callouts below:

// test-class.ts
import { IsString, IsOptional } from 'class-validator';

export class TestClass {
  @IsString()
  address1: string;

  @IsString()
  @IsOptional()
  address2?: string;
}
//test-valid.controller.ts
import { Controller, Post, Body, UsePipes, ValidationPipe } from '@nestjs/common';
import { TestClass } from './models/test-class';

@Controller('test-valid')
export class TestValidController {

  @Post()
  @UsePipes(new ValidationPipe({skipMissingProperties: true}))
  @UsePipes(new ValidationPipe({forbidNonWhitelisted: true, whitelist: true, transform: true}))
  async testValidate(@Body() body: TestClass) {
    return 'Valid!';
  }
}

# cURL callouts 
~/Documents/gitRepos/nest-testing
$ curl -X POST http://localhost:3000/test-valid \
> --header "Content-Type: application/json" \
> --data '{"address1": "some address", "address2": "some other address"}'
Valid!

~/Documents/gitRepos/nest-testing
$ curl -X POST http://localhost:3000/test-valid --header "Content-Type: a
pplication/json" --data '{"address2": "some other address"}'
[{"target":{"address2":"some other address"},"property":"address1","children":[],"constraints":{"isString":"address1 must be a string"}}]

~/Documents/gitRepos/nest-testing
$ curl -X POST http://localhost:3000/test-valid --header "Content-Type: a
pplication/json" --data '{"address1": "some address"}'
Valid!

You can see if address1 is missing class-validator will throw an error .

Looking at your code, you have required: true right above your address1: string and not in a decorator, that could be causing an issue of the decorators being applied to the field required instead of address1, just something I thought I'd point out.

like image 177
Jay McDoniel Avatar answered Dec 10 '25 00:12

Jay McDoniel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!