I'm trying to validate parameters of my PUT users/ endpoint but I'd like that all parameters are optional but once the api consumer fill these parameters I'd like to validate them.

I tried to combined @ApiModelProperty required false with validation pipes decorator but validation pipe took over ApiModelProperty (pretty normal for sending 400 bad request HttpException)

Here is my DTO: usersUpdate.dto.ts

import { IsEmail, IsEnum, IsPhoneNumber, IsEmpty } from 'class-validator';
import { ApiModelProperty } from '@nestjs/swagger';
import { RoleType } from './role-type.enum';

class UserInfo {
    @ApiModelProperty({ description: 'User firstname', required: false  })
    readonly firstname: string;

    @ApiModelProperty({ description: 'User lastname', required: false  })
    readonly lastname: string;

    @ApiModelProperty({description: 'User postal address', required: false })
    readonly address: string;

    @ApiModelProperty({ description: 'User phone number', required: false  })
    @IsPhoneNumber('FR')
    readonly phone: string;

    @ApiModelProperty({ description: 'User siret number', required: false  })
    readonly siret: string;
}

export class UpdateUserDTO {
    @ApiModelProperty({ description: 'User email address', required: false })
    readonly email: string;

    @ApiModelProperty({ description: 'User password', required: false })
    readonly password: string;

    @ApiModelProperty({ description: 'User informations', required: false })
    readonly user_info: UserInfo;

    @ApiModelProperty({ enum: ['Admin', 'Runner', 'Dispatcher'], description:'User role',  required: false })
    readonly role: RoleType;

    @ApiModelProperty({ description: 'User activation token', required: false })
    readonly activationToken: string;
}

I would like to use and @IsEmail() decorator on email parameter and a @Enum() decorator in role but once I use these decorator the parameter is mandatory.

Anybody know how to skip this validator if parameters are empty ?

1 Answers

1
A. Maitre On

Yes, you can let the validators be optional on fields by applying the @IsOptional decorator from class-validator.

Another thing that you could use instead of @ApiModelProperty({ description: 'User activation token', required: false }) is @ApiModelPropertyOptional and thus remove the required: false part of the declaration.

Finally you can even make use of @IsEmail() decorator to validate the email field is an email, and last thing you can do is combine @IsNotEmpty() and @IsOptional() so that when a field is provided it should not be empty.

Provided code would look like this:

    import { IsEmail, IsEnum, IsPhoneNumber, IsEmpty, IsOptional } from 'class-validator';
    import { ApiModelPropertyOptional } from '@nestjs/swagger';
    import { RoleType } from './role-type.enum';

    class UserInfo {
        @ApiModelPropertyOptional({ description: 'User firstname' })
        @IsOptional()
        readonly firstname: string;

        @ApiModelPropertyOptional({ description: 'User lastname' })
        @IsOptional()
        readonly lastname: string;

        @ApiModelPropertyOptional({description: 'User postal address' })
        @IsOptional()
        readonly address: string;

        @ApiModelPropertyOptional({ description: 'User phone number'  })
        @IsOptional()
        @IsPhoneNumber('FR')
        readonly phone: string;

        @ApiModelPropertyOptional({ description: 'User siret number'  })
        @IsOptional()
        readonly siret: string;
    }

    export class UpdateUserDTO {
        @ApiModelPropertyOptional({ description: 'User email address' })
        @IsEmail()
        @IsOptional()
        readonly email: string;

        @ApiModelPropertyOptional({ description: 'User password' })
        @IsOptional()
        readonly password: string;

        @ApiModelPropertyOptional({ description: 'User informations' })
        @IsOptional()
        readonly user_info: UserInfo;

        @ApiModelPropertyOptional({ enum: ['Admin', 'Runner', 'Dispatcher'], description:'User role' })
        @IsEnum(RoleType)
        @IsOptional()
        readonly role: RoleType;

        @ApiModelPropertyOptional({ description: 'User activation token' })
        @IsOptional()
        readonly activationToken: string;
    }

Let me know if it helps ;)