Skip to main content

Validation

For validation of network request payload, Nest.js officially recommends using class-validator with Pipe to implement the validation feature 1.

The class-validator requires you to define a corresponding class/DTO for each data object that needs to be validated, which can make things cumbersome if the data object has multiple layers of nested structures.

And if you write DTOs just to validate the request payload, the DTOs are a bit redundant, because after all, the type of request payload may not be the same as the one actually used in service, you need to do further processing of the payload into the required type structure in service.

Validation using Yup

Nest.js Extends Toolkit provides a set of decorators based on Yup for request payload validation.

To begin using it, we first install the required dependency.

npm i --save yup

Depending on your needs, you can use different decorators:

DecoratorData Source
@YupValidatedBody(schema: Yup.ObjectSchema)req.body
@YupValidatedParam(key: string, schema: Yup.Schema)req.params[key]
@YupValidatedParams(schema: Yup.Schema)req.params
@YupValidatedQuery(key: string, schema: Yup.Schema)req.query[key]
@YupValidatedQueries(schema: Yup.Schema)req.query

Example

import { Controller, Get, Post } from '@nestjs/common';
import { YupValidatedBody, YupValidatedParam, YupValidatedParams, YupValidatedQueries, YupValidatedQuery } from 'nestjs-extends';
import * as Yup from 'yup';

const GetCatsParamsValidation = Yup.object({
roomId: Yup.number().integer().required(),
}).required()

const CatColorValidation = Yup.string().required().oneOf(['white', 'black', 'blue'])
const GetCatsQueriesValidation = Yup.object({
color: CatColorValidation,
age: Yup.number().integer().required(),
}).required()

const AddCatBodyValidation = Yup.object({
name: Yup.string().required(),
color: CatColorValidation,
age: Yup.number().integer().required(),
}).required()

@Controller()
export class CatsController {
@Get('/rooms/:roomId/cats')
getCats(
@YupValidatedParam('roomId', Yup.number().integer().required()) roomId: number,
@YupValidatedParams(GetCatsParamsValidation.required()) params: Yup.InferType<typeof GetCatsParamsValidation>,
@YupValidatedQuery('color', CatColorValidation.required()) color: Yup.InferType<typeof CatColorValidation>,
@YupValidatedQueries(GetCatsQueriesValidation) queries: Yup.InferType<typeof GetCatsQueriesValidation>,
): string {
return 'This action returns cats';
}

@Post('/rooms/:roomId/cats')
addCat(
@YupValidatedParam('roomId', Yup.number().integer().required()) roomId: number,
@YupValidatedBody(AddCatBodyValidation) body: Yup.InferType<typeof AddCatBodyValidation>,
): string {
return 'This action add new cat to room';
}
}

Validation using Zod

Nest.js Extends Toolkit also provides a set of decorators based on Zod for request payload validation.

To begin using it, we first install the required dependency.

npm i --save zod

Depending on your needs, you can use different decorators:

DecoratorData Source
@ZodValidatedBody(schema: z.ZodObject)req.body
@ZodValidatedParam(key: string, schema: z.ZodType)req.params[key]
@ZodValidatedParams(schema: z.ZodObject)req.params
@ZodValidatedQuery(key: string, schema: z.ZodType)req.query[key]
@ZodValidatedQueries(schema: z.ZodObject)req.query

It is similar to Yup based decorators, please refer to the examples above.