nestjs 管道的简单介绍

189 阅读4分钟

pipi(管道)

在nestjs中,管道是一种有用的技术,用于在请求处理过程中转化、验证、或处理数据。在nestjs中,管道分为两类:Input Pipes( 输入管道 )和 Output Pipes( 输出管道 )。

Input Pipes

Input Pipes(输入管道)的主要作用是在处理之前对请求进来的数据进行预处理。例如,验证和转化数据类型。nestjs已经内置了一些输入管道,可以让你更加方便地操作请求进来的数据。

  1. Validation Pipe(验证管道): 这个管道可以验证在传入请求体之前数据是否符合特定的约束。nestjs使用了一个第三方库class-validator来执行验证。举个例子,看看如何在nestjs中通过一个简单的验证管道来验证请求体中的数据:

    import { Controller, Get, Body, Post } from '@nestjs/common';
    import { CreateCatDto } from './create-cat.dto';
    import { CatsService } from './cats.service';
    import { ValidationPipe } from '@nestjs/common';
    
    @Controller('cats')
    export class CatsController {
      constructor(private catsService: CatsService) {}
    
      @Post()
      async create(@Body(new ValidationPipe()) createCatDto: CreateCatDto) {
        await this.catsService.create(createCatDto);
      }
    }
    
  2. ParseInt Pipe(解析整数管道): 这个管道可以把传递过来的字符串型的数字转化为整型。这主要用于query中的参数转化,比如:{ /cats?limit=10 }在nestjs中的实现如下:

    import { Controller, Get, Query } from '@nestjs/common';
    import { CatsService } from './cats.service';
    import { ParseIntPipe } from '@nestjs/common';
    
    @Controller('cats')
    export class CatsController {
      constructor(private catsService: CatsService) {}
    
      @Get()
      async findAll(@Query('limit', new ParseIntPipe()) limit: number) {
        return this.catsService.findAll();
      }
    }
    

    上面的代码将会把查询字符串(limit)转化为一个整型。如果无法进行转化,就会抛出一个 BadRequestException(错误请求)。

  3. Default value Pipe(默认值管道): 这个管道用于在某些时候为参数设置一个默认值。举个例子,让我们看看如何在nestjs中为一个参数提供一个默认值:

    import { Controller, Get, Query } from '@nestjs/common';
    import { CatsService } from './cats.service';
    import { DefaultValuePipe } from '@nestjs/common';
    
    @Controller('cats')
    export class CatsController {
      constructor(private catsService: CatsService) {}
    
      @Get()
      async findAll(@Query('page', new DefaultValuePipe(1)) page: number) {
        return this.catsService.findAll();
      }
    }
    

    在上面的代码中,如果查询字符串中没有page这个参数值,那么这个参数就会被设置为默认值1。

Output Pipes

Output Pipes(输出管道)的作用是对返回的数据进行操作和转换,这些操作是在数据离开控制器发送响应之前进行的一些额外步骤。既然是输出,也就是返回数据的最后一步转换,所以它更常用来进行数据加工、格式化等转换。

nestjs中的输出管道只有一个,那就是Transform Pipe(转换管道),用于把控制器函数内返回的结果进行转换的操作。举个例子,看看如何在nestjs中使用Transform Pipe来转化数据:

import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Transform } from 'class-transformer';

@Controller('cats')
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @Get()
  @Transform(({ value }) => ({ cats: value }))
  findAll() {
    return this.catsService.findAll();
  }
}

在上面的代码中,我可以看到,传递给Transform管道的参数是一个包含value属性的对象,该对象表示当前控制器返回的结果,再对结果进行一次处理。

全局使用管道

在nestjs中,可以使用useGlobalPipes()方法将ValidationPipe应用于整个应用程序,以便对所有控制器中的传入请求进行验证。通过这种方式,我们可以确保所有控制器的输入都被验证并符合预期。

以下是如何使用useGlobalPipes()方法将ValidationPipe应用于整个nestjs应用程序的示例:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from './validation.pipe';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();

在上面的代码中,使用了useGlobalPipes()方法将全局管道ValidationPipe应用到整个nestjs应用程序,以便对所有控制器中的传入请求进行验证。

如果需要重写全局管道的设置,可以在特定控制器方法上使用@UsePipes()装饰器。例如,如果需要为特定方法禁用全局ValidationPipe验证,您可以使用以下代码:

import { Controller, Post, UsePipes } from '@nestjs/common';
import { ValidationPipe } from 'src/validation.pipe';

@Controller('users')
export class UsersController {

  @Post()
  @UsePipes()
  async create() {
    // ...
  }
}

在上面的代码中,针对create()方法使用了一个空的参数列表来禁用全局ValidationPipe验证,这意味着我们需要手动进行输入验证。

总之,使用useGlobalPipes()方法将ValidationPipe应用于整个nestjs应用程序中的所有输入请求的步骤,以确保所有控制器的输入都被验证并符合预期。