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
支持自定义 可实现任何自定义输入处理逻辑
可全局注册 让所有请求自动校验
相关推荐
hboot1 小时前
AI工程师第一课 - Python
前端·后端·python
凉菜凉凉1 小时前
AI时代,被抛弃的前端
前端·ai
console.log('npc')1 小时前
AI前端工程与生成式UI学习路线
前端·人工智能·ui
梦曦i2 小时前
uni-router v1.1.1发布:守卫超时保护+路由监听
前端·uni-app
qq_2518364572 小时前
基于java Web网络订餐系统设计与实现 源码文档
java·开发语言·前端
飞天狗1112 小时前
零基础JavaWeb入门——第2课:让网页“活”起来 —— JSP是什么?
java·开发语言·前端·后端·web
回忆2012初秋3 小时前
【Nginx】优雅地走进高性能 Web 服务器世界(1)
服务器·前端·nginx
kyriewen3 小时前
Claude Code Token 烧太快?实测 5 招,把月费从 250 美金砍到 50 美金
前端·ai编程·claude
weixin_394758034 小时前
CRMEB Pro 商品字段二开:为什么加一个字段会牵动 SKU、缓存和前端展示?
前端·缓存