管道简介

Nest.js 的管道(Pipes)用于处理输入数据的转化和验证。能够执行以下任务:

  1. 验证(Validation):保证传入恳求的数据符合某些标准,假如数据无效,则能够抛出反常。
  2. 转化(Transformation):将输入数据转化成期望的办法,例如从字符串转化成整数,或许从用户输入的日期字符串转化为 Date 目标。

管道有两种类型:

  1. 内置管道:Nest.js 提供了一些内置的管道,例如 ValidationPipeParseIntPipe 等。
  2. 自定义管道:用户能够创立自定义管道来满足特定的需求。

咱们先来介绍内置管道。

内置管道

Nest 内置的 Pipe:

  • ValidationPipe
  • ParseIntPipe
  • ParseBoolPipe
  • ParseArrayPipe
  • ParseUUIDPipe
  • DefaultValuePipe
  • ParseEnumPipe
  • ParseFloatPipe
  • ParseFilePipe

创立项目:

nest new pipe-test -p npm

ParseIntPipe

ParseIntPipe 转化参数为整数,无法转化或许转化后不是整数则抛出反常:

Nest 管道:数据验证与转化的利器

访问页面能够看出 age 是字符串,因为字符串 + 数字才会拼接:
Nest 管道:数据验证与转化的利器

咱们运用 ParseIntPipe
Nest 管道:数据验证与转化的利器

正确相加:
Nest 管道:数据验证与转化的利器

传递一个无法转化整数的会报错:

Nest 管道:数据验证与转化的利器

咱们还能够自定义错误:
Nest 管道:数据验证与转化的利器

从头访问:
Nest 管道:数据验证与转化的利器

这里也能够经过 exceptionFactory 选项自定义反常工厂函数,抛出反常,让反常过滤器自己处理。

ParseFloatPipe

ParseFloatPipe 是将参数转化为浮点数:

Nest 管道:数据验证与转化的利器

访问下:
Nest 管道:数据验证与转化的利器

相同支撑 new ParseFloatPipe 的办法,可传入 errorHttpStatusCode 和 exceptionFactory 选项自定义错误。

ParseBoolPipe

ParseBoolPipe 用于将输入的字符串转化为布尔值。假如输入的值无法转化为布尔值,则会抛出反常。

Nest 管道:数据验证与转化的利器

ParseEnumPipe

ParseEnumPipe 用于保证输入的值是特定枚举中的一个有用值。假如输入的值不在枚举中,则会抛出反常。

Nest 管道:数据验证与转化的利器

Nest 管道:数据验证与转化的利器

假如 role 的值不是 admin 或 user,则会抛出 BadRequestException。
也相同能够经过 errorHttpStatusCode 和 exceptionFactory 来自定义错误。

ParseUUIDPipe

ParseUUIDPipe 用于验证输入的字符串是否是有用的 UUID(通用仅有标识符)。假如不是有用的 UUID,则会抛出反常。
咱们用 uuid 包能够生成 uuid:

Nest 管道:数据验证与转化的利器

Nest 管道:数据验证与转化的利器

Nest 管道:数据验证与转化的利器

DefaultValuePipe

DefaultValuePipe 用于为参数提供一个默认值:

Nest 管道:数据验证与转化的利器

Nest 管道:数据验证与转化的利器

ParseArrayPipe

用于将客户端发送的字符串数组解析为实际的数组类型:
先装置 class-validator 包,这是能够用装饰器和非装饰器两种办法对 class 属性做验证的库。
再装置 class-transformer 包,它是把一般目标转化为对应的 class 实例的包。

npm install class-validator class-transformer -D

Nest 管道:数据验证与转化的利器

Nest 管道:数据验证与转化的利器

还剩余 ValidationPipe 和 ParseFilePipe,之后再讲。

运用管道的 4 种办法

管道不仅支撑对某个参数等级生效,也能对整个 Controller 、办法、大局都生效。

// 参数等级的 Pipes
@Get(':id')
getUserById(@Param('id', ParseIntPipe) id: number) {
  // ...
}
// Controller 生效
@Controller('users')
@UsePipes(ValidationPipe)
export class UsersController {
  // ...
}
// 办法等级的 Pipes
@Controller('users')
export class UsersController {
  @Post()
  @UsePipes(ValidationPipe)
  createUser(@Body() createUserDto: CreateUserDto) {
    // ...
  }
}
// 大局 Pipes
import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';
import { ValidationPipe } from './pipes/validation.pipe';
@Module({
  providers: [
    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
  ],
})
export class AppModule {}

创立自定义管道

创立自定义管道,需要实现 PipeTransform 接口,并定义 transform 办法。
下面管道,它将输入字符串转化为整数:

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
@Injectable()
export class ParseIntPipe implements PipeTransform<string, number> {
  transform(value: string, metadata: ArgumentMetadata): number {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}

运用这个自定义管道:

import { Controller, Get, Query, UsePipes } from '@nestjs/common';
import { ParseIntPipe } from './parse-int.pipe';
@Controller('numbers')
export class NumbersController {
  @Get()
  @UsePipes(ParseIntPipe)
  async getNumber(@Query('num') num: number): Promise<number> {
    // num 参数现已被 ParseIntPipe 转化为整数
    return num;
  }
}

当客户端发起恳求并传递 num 查询参数时,ParseIntPipe 会自动将 num 转化为整数类型,然后传递给 getNumber 办法。