管道是具有 @Injectable() 装饰器的类。管道应实现 PipeTransform 接口。
一、什么是 Pipe?
管道(Pipes) 是请求生命周期中的核心组件之一,主要用于在控制器方法执行之前对传入的参数进行转换(Transformation) 或验证(Validation) 。
简单来说,管道就像是一个“关卡”,数据在进入你的业务逻辑代码之前,必须先经过这个关卡的处理。
如果数据不合法,管道可以直接抛出异常阻止请求继续;如果数据需要格式化,管道可以将其转换后再交给控制器。
在框架生命周期中,它的执行时机是:
请求进入 → 中间件 → 守卫 → 拦截器 →
管道→ 控制器 → 服务 → 拦截器 → 异常过滤器 → 服务器响应
二、怎么使用
Pipe 有两个核心能力:NestJS 已经内置了一些常用 Pipe,也支持你自定义 Pipe。
1. 内置 Pipe 示例
转换:ParseIntPipe
比如我们有一个路由 /user/:id:
@Get(':id')
getUser(@Param('id', ParseIntPipe) id: number) {
console.log(typeof id); // number
return `User ID: ${id}`;
}
请求 /user/123 时:
- 默认参数是字符串
'123' ParseIntPipe会自动转换成数字123- 控制器拿到的就是正确的类型
如果传 /user/abc,NestJS 会自动报错:
BadRequestException: Validation failed (numeric string is expected)
验证:ValidationPipe
这个是最常用的管道,用于 DTO 校验。 比如我们定义一个创建用户的 DTO:
// create-user.dto.ts
import { IsString, IsInt, MinLength } from 'class-validator';
export class CreateUserDto {
@IsString()
@MinLength(3)
name: string;
@IsInt()
age: number;
}
然后在控制器中这样用:
@Post()
createUser(@Body(new ValidationPipe()) body: CreateUserDto) {
return body;
}
请求:
{ "name": "Li", "age": "20" }
- ✅
ValidationPipe会自动把"20"转成number - ✅ 校验
name长度、age是否为数字 - ❌ 如果不合法,直接抛出 400 错误
2. 自定义 Pipe 示例
我们也可以自己写一个 Pipe,比如让所有输入字符串转成小写:
import { PipeTransform, Injectable } from '@nestjs/common';
@Injectable()
export class ToLowerCasePipe implements PipeTransform {
transform(value: any) {
return typeof value === 'string' ? value.toLowerCase() : value;
}
}
使用:
@Get()
getUser(@Query('name', ToLowerCasePipe) name: string) {
return `Hello ${name}`;
}
请求:
GET /user?name=LiBai
控制器拿到的就是:
Hello libai
3. 全局注册 Pipe
如果你希望整个项目的请求参数都经过校验,可以全局注册 Pipe:
// main.ts
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe({
transform: true, // 自动类型转换
whitelist: true, // 自动去掉未在 DTO 声明的属性
forbidNonWhitelisted: true, // 多余属性直接报错
}));
await app.listen(3000);
}
bootstrap();
这样,全项目所有 DTO 都能自动验证输入参数。
三、使用场景
| 能力 | 说明 |
|---|---|
| 转换 (Transform) | 把输入值转成想要的类型或格式 |
| 验证 (Validate) | 检查输入是否符合要求,不符合就抛异常 |
它在请求到达 Controller 控制器 之前,会先对传入的参数做一些“处理”:
- ✅ 转换类型(比如
'123'→123) - ✅ 验证合法性(比如检查邮箱格式、必填字段)
- ✅ 清洗或格式化数据(比如字符串转小写)
四、总结
Pipe 就是 NestJS 里处理“输入数据”的守门员,它让你的控制器拿到的数据始终是干净、正确、可信的。
| 功能 | 说明 |
|---|---|
| Pipe 是什么 | NestJS 中用于处理请求参数的中间环节 |
| 两大功能 | 转换(Transform) + 校验(Validate) |
| 执行时机 | 控制器执行前 |
| 常用内置 Pipe | ValidationPipe、ParseIntPipe、ParseBoolPipe、DefaultValuePipe |
| 支持自定义 | 可实现任何自定义输入处理逻辑 |
| 可全局注册 | 让所有请求自动校验 |