NestJS DTO 类设置类验证器和类转换器执行顺序

作者:编程家 分类: typescript 时间:2025-06-20

NestJS是一个用于构建高效、可扩展的Node.js服务器端应用程序的框架。在开发过程中,我们经常需要对传入的数据进行验证和转换,以确保数据的完整性和准确性。为了实现这一目标,NestJS提供了DTO(数据传输对象)类来定义数据的结构和验证规则。同时,我们还可以使用类验证器和类转换器来对DTO类进行进一步的处理。本文将介绍如何设置类验证器和类转换器的执行顺序,并提供了一些案例代码来帮助读者更好地理解。

什么是类验证器和类转换器?

在NestJS中,类验证器和类转换器是用来处理DTO类的两个重要概念。类验证器用于验证传入的数据是否符合预定义的规则,例如数据类型、长度、格式等。而类转换器则用于将传入的数据转换为DTO类所需的格式,例如将字符串转换为日期对象、将数字字符串转换为整数等。

类验证器的执行顺序

当我们使用@UsePipes()装饰器将类验证器应用到路由处理方法上时,类验证器会按照定义的顺序逐个执行。如果其中一个类验证器失败(即验证规则不通过),则后续的类验证器将不会执行,NestJS会立即返回错误响应。

考虑以下示例代码:

typescript

// user.dto.ts

import { IsString, IsNotEmpty } from 'class-validator';

export class CreateUserDto {

@IsString()

@IsNotEmpty()

name: string;

@IsString()

@IsNotEmpty()

email: string;

}

typescript

// user.controller.ts

import { Controller, Post, Body, UsePipes } from '@nestjs/common';

import { ValidationPipe } from './validation.pipe';

import { CreateUserDto } from './user.dto';

@Controller('users')

export class UserController {

@Post()

@UsePipes(new ValidationPipe())

createUser(@Body() createUserDto: CreateUserDto) {

// 处理创建用户的逻辑

}

}

在上述示例中,我们定义了一个CreateUserDto类,并使用了class-validator库中的装饰器对name和email属性进行验证。在UserController类中,我们将ValidationPipe类装饰器应用到createUser方法上。当请求到达createUser方法时,NestJS会先执行ValidationPipe类验证器,然后再执行createUser方法。

类转换器的执行顺序

与类验证器类似,当我们使用@UsePipes()装饰器将类转换器应用到路由处理方法上时,类转换器也会按照定义的顺序逐个执行。同样地,如果其中一个类转换器失败(即转换失败),则后续的类转换器将不会执行,NestJS会立即返回错误响应。

考虑以下示例代码:

typescript

// user.dto.ts

import { IsString } from 'class-validator';

import { Transform } from 'class-transformer';

export class CreateUserDto {

@IsString()

@Transform(({ value }) => value.toUpperCase())

name: string;

}

typescript

// user.controller.ts

import { Controller, Post, Body, UsePipes } from '@nestjs/common';

import { TransformationPipe } from './transformation.pipe';

import { CreateUserDto } from './user.dto';

@Controller('users')

export class UserController {

@Post()

@UsePipes(new TransformationPipe())

createUser(@Body() createUserDto: CreateUserDto) {

// 处理创建用户的逻辑

}

}

在上述示例中,我们使用了class-transformer库中的Transform装饰器将name属性的值转换为大写。在UserController类中,我们将TransformationPipe类装饰器应用到createUser方法上。当请求到达createUser方法时,NestJS会先执行TransformationPipe类转换器,然后再执行createUser方法。

类验证器和类转换器的执行顺序

当我们同时使用类验证器和类转换器时,它们的执行顺序与装饰器的定义顺序有关。具体来说,类验证器会在类转换器之前执行。

考虑以下示例代码:

typescript

// user.dto.ts

import { IsString, IsEmail } from 'class-validator';

import { Transform } from 'class-transformer';

export class CreateUserDto {

@IsString()

@Transform(({ value }) => value.toUpperCase())

name: string;

@IsEmail()

@Transform(({ value }) => value.toLowerCase())

email: string;

}

typescript

// user.controller.ts

import { Controller, Post, Body, UsePipes } from '@nestjs/common';

import { ValidationPipe } from './validation.pipe';

import { TransformationPipe } from './transformation.pipe';

import { CreateUserDto } from './user.dto';

@Controller('users')

export class UserController {

@Post()

@UsePipes(new ValidationPipe(), new TransformationPipe())

createUser(@Body() createUserDto: CreateUserDto) {

// 处理创建用户的逻辑

}

}

在上述示例中,我们将ValidationPipe类验证器和TransformationPipe类转换器同时应用到createUser方法上。当请求到达createUser方法时,NestJS会先执行ValidationPipe类验证器,然后再执行TransformationPipe类转换器。

通过本文,我们了解了NestJS中类验证器和类转换器的执行顺序。类验证器用于验证传入的数据是否符合预定义的规则,而类转换器则用于将传入的数据转换为DTO类所需的格式。在使用这两个功能时,我们需要注意它们的执行顺序,并确保按照我们的需求正确地配置它们。希望本文能帮助读者更好地理解NestJS中类验证器和类转换器的工作原理,并在实际开发中得到应用。