Nest JS class-validators complex examples to make life easier in project

Shivam Gupta
4 min readApr 10, 2023

Hello I am working in JavaScript related technologies from last 5+ years, currently working as Full stack engineer in Cardekho, Product based company in India.

From last 2 years, I started working In NestJS which is a typescript based framework. I developed 3 microservices using NestJs in a single project —

  1. Http Api Microservice
  2. Cron Microservice
  3. Consumer Microservice

On every micro service, We need to write class validators to validate input parameters, API Request Body & Query Params.

IN some cases class-validators are very typical and no documentation found , if you want to perform some complex validation, let me share some of great examples may made your life easier

Validate Array Of Mobile numbers

Input [“abc”, “8789”], error: “each value in mobile_numbers must match ^[5–9][0–9]{9}$ regular expression”

Validate Array Of objects

Input has buttons array with an Object
Example class validator example

Lets go more deeper in class validators —

1. Validating String

Any String

// example.dto.ts
import {
IsString,
IsNotEmpty,
MinLength,
MaxLength
} from 'class-validator'

export class AnyString {
@IsString()
@IsNotEmpty()
@MinLength(3)
@MaxLength(65)
userName: string
}

Specific String

// example.dto.tsty
import {
ArrayNotEmpty,
IsArray,
IsIn
} from 'class-validator'

const weekdays = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'];
export class SpecificString {
@IsArray()
@ArrayNotEmpty()
@IsIn(weekdays)
day: string[]
}

Array of strings

// example.dto.ts
import {
ArrayNotEmpty,
Contains,
IsArray,
IsString,
Matches,
MaxLength
} from 'class-validator'

export class StringArray {
@IsArray()
@ArrayNotEmpty()
// check if every array item is string
@IsString({ each: true })
// Pass `each: true` when you want this validation to run on every array item
// Check if every array item has max length
@MaxLength(6, { each: true })
// Check if every array item is only alphabets
@Matches('^[a-zA-Z\\s]+$', undefined, { each: true })
// CHeck if every array item contains a text
@Contains('hello', { each: true })
stringArray: string[]
}

Array of Strings with a custom prefix

// example.dto.ts
import {
ArrayNotEmpty,
IsArray,
Validate,
ValidateNested,
ValidatorConstraint,
ValidatorConstraintInterface
} from 'class-validator'

@ValidatorConstraint({ name: 'arrayPrefixValidator' })
export class ArrayPrefixValidator implements ValidatorConstraintInterface {
validate(values: string[] = []): boolean {
if (values.length) {
return values.every((value) => value.startsWith('str-'))
}
return false
}
}
export class StringArray {
@IsArray()
@ArrayNotEmpty()
// Check if every array item contains a prefix str-
@Validate(ArrayPrefixValidator, { message: 'No str- prefix' })
stringArray: string[]
}

2️. Validating Number

Any number

import {
IsNumber,
IsNotEmpty,
MinLength,
MaxLength
} from 'class-validator'
export class AnyString {
@IsNumber()
@IsNotEmpty()
@MinLength(3)
@MaxLength(65)
userName: string
}

Specific Number

import {
IsNumber,
IsNotEmpty,
MinLength,
MaxLength,
ValidatorConstraint,
ValidatorConstraintInterface
} from 'class-validator'
@ValidatorConstraint({ name: 'isDividedBy17' })
export class IsDividedBy17 implements ValidatorConstraintInterface {
validate(value: number): boolean {
if (value {
return value % 17 === 0
}
return false
}
}
export class SpecificNumber {
@IsNumber()
@IsNotEmpty()
// Check if number is divisible by 17
@Validate(IsDividedBy17, { message: 'No divided by 17' })
specificNumber: number
}

Array of numbers

import {
IsNumber,
IsNotEmpty,
MinLength,
MaxLength,
ValidatorConstraint,
ValidatorConstraintInterface
} from 'class-validator'

@ValidatorConstraint({ name: 'isEvenNumber' })
export class IsEvenNumber implements ValidatorConstraintInterface {
validate(numbers: number): boolean {
if (numbers {
return numbers.every(number => number % 2 === 0)
}
return false
}
}
export class SpecificNumber {
@IsNumber()
@IsNotEmpty()
// Check if everynumber is even
@Validate(IsEvenNumber, { message: 'No divided by 17' })
numbersList: number[]
}

3️. Custom Object

For example you have a payload like below

{
jsom movies: [{
name: "The jurassic park",
yearOfRelease: 1999,
languages: ["en"]
gener: ["sci-fi", "thriller"]
},
{
name: "The Croods",
yearOfRelease: 2012,
languages: ["en", "fr", "es"]
gener: ["animation", "kids"]
}]
}
import {
IsNumber,
IsNotEmpty,
MinLength,
MaxLength,
ValidatorConstraint,
ValidatorConstraintInterface
} from 'class-validator'

@ValidatorConstraint({ name: 'isEvenNumber' })
export class IsEvenNumber implements ValidatorConstraintInterface {
validate(numbers: number): boolean {
if (numbers {
return numbers.every(number => number % 2 === 0)
}
return false
}
}
const validLanguages = ["en", "es", "fr"]
const validGeneres = ["sci-fi", "thriller", "animation", "horror", "vintage"]
// 💡 Types here
export class Movie {
@IsString()
@IsNotEmpty()
@ISRequired()
name: string
@IsNotEmpty()
@IsNumber()
@ISRequired()
yearOfRelease: number
@IsNotEmpty()
@IsString()
@IsIn(validLanguages)
@ISRequired()
languages: string[]
@IsNotEmpty()
@IsString()
@IsIn(validGeneres)
@ISRequired()
genre: string[]
}
export class MoviesList {
@IsArray()
@ArrayNotEmpty()
@Type(() => Movie)
movies: Movie[]
}

Please write in comment section if this was helpful in your use case, also u can write if need any help in your project.

References

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Shivam Gupta
Shivam Gupta

Written by Shivam Gupta

Full Stack Engineer (Web/App) working on different JS Technologies & frameworks— Angular, Node, Typescript, Ionic, Firebase, AWS, ElK...Love to write cool stuff

No responses yet

Write a response