nestjs学习 - 管道(pipe)

管道是具有 @Injectable() 装饰器的类。管道应实现 PipeTransform 接口。

一、什么是 Pipe?

管道(Pipes) 是请求生命周期中的核心组件之一,主要用于在控制器方法执行之前 对传入的参数进行转换(Transformation)验证(Validation)

简单来说,管道就像是一个"关卡",数据在进入你的业务逻辑代码之前,必须先经过这个关卡的处理。

如果数据不合法,管道可以直接抛出异常阻止请求继续;如果数据需要格式化,管道可以将其转换后再交给控制器。

在框架生命周期中,它的执行时机是:

请求进入 → 中间件 → 守卫 → 拦截器 → 管道 → 控制器 → 服务 → 拦截器 → 异常过滤器 → 服务器响应

二、怎么使用

Pipe 有两个核心能力:NestJS 已经内置了一些常用 Pipe,也支持你自定义 Pipe。

1. 内置 Pipe 示例

转换:ParseIntPipe

比如我们有一个路由 /user/:id

less 复制代码
@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 会自动报错:

vbnet 复制代码
BadRequestException: Validation failed (numeric string is expected)

验证:ValidationPipe

这个是最常用的管道,用于 DTO 校验。 比如我们定义一个创建用户的 DTO:

less 复制代码
// create-user.dto.ts
import { IsString, IsInt, MinLength } from 'class-validator';
​
export class CreateUserDto {
  @IsString()
  @MinLength(3)
  name: string;
​
  @IsInt()
  age: number;
}

然后在控制器中这样用:

less 复制代码
@Post()
createUser(@Body(new ValidationPipe()) body: CreateUserDto) {
  return body;
}

请求:

json 复制代码
{ "name": "Li", "age": "20" }
  • ValidationPipe 会自动把 "20" 转成 number
  • ✅ 校验 name 长度、age 是否为数字
  • ❌ 如果不合法,直接抛出 400 错误

2. 自定义 Pipe 示例

我们也可以自己写一个 Pipe,比如让所有输入字符串转成小写:

typescript 复制代码
import { PipeTransform, Injectable } from '@nestjs/common';
​
@Injectable()
export class ToLowerCasePipe implements PipeTransform {
  transform(value: any) {
    return typeof value === 'string' ? value.toLowerCase() : value;
  }
}

使用:

less 复制代码
@Get()
getUser(@Query('name', ToLowerCasePipe) name: string) {
  return `Hello ${name}`;
}

请求:

ini 复制代码
GET /user?name=LiBai

控制器拿到的就是:

复制代码
Hello libai

3. 全局注册 Pipe

如果你希望整个项目的请求参数都经过校验,可以全局注册 Pipe:

javascript 复制代码
// 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 ValidationPipeParseIntPipeParseBoolPipeDefaultValuePipe
支持自定义 可实现任何自定义输入处理逻辑
可全局注册 让所有请求自动校验
相关推荐
梦鱼1 小时前
🖥️ 告别 Electron 托盘图标模糊:一套精准的 PNG 生成方案
前端·electron
张元清1 小时前
React Hooks 性能优化:如何避免不必要的重新渲染
前端·javascript·面试
不甜情歌2 小时前
JavaScript this绑定规则:告别踩坑指南!
前端·javascript
小J听不清2 小时前
CSS 三种引入方式全解析:行内 / 内部 / 外部样式表(附优先级规则)
前端·javascript·css·html·css3
aircrushin2 小时前
端到端AI决策架构如何重塑实时协作体验?
前端·javascript·后端
AI前端老薛2 小时前
前端开发神器 - Image Preview插件
前端
Predestination王瀞潞3 小时前
2.4 编码->W3C XML 1.0标准(W3C Recommendation):XML(Extensible Markup Language)
xml·前端
FlyWIHTSKY3 小时前
vue3中const的使用和定义
前端·javascript·vue.js
小璐资源网3 小时前
如何写出干净、易维护的 HTML 结构
前端·html