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:
Decorator | Data 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:
Decorator | Data 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.