nestjs学习 - 管道(pipe)

0 阅读2分钟

管道是具有 @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)
执行时机控制器执行前
常用内置 PipeValidationPipeParseIntPipeParseBoolPipeDefaultValuePipe
支持自定义可实现任何自定义输入处理逻辑
可全局注册让所有请求自动校验