TMDOG的微服务之路_05——Nest.js 的管道使用

TMDOG的微服务之路_05——Nest.js 的管道使用

博客地址:TMDOG的博客

在上一篇博客中,我们探讨了如何在 Nest.js 中使用异常筛选器。本篇博客,我们将深入了解如何在 Nest.js 中使用管道进行数据验证和转换。

使用内置管道

1. 在控制器中使用内置管道

我们在原有的代码基础上修改:

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get(':id')
  getHello(@Param('id', new ParseIntPipe()) id: number): string {
    return (this.appService.getHello() + id + typeof id);
  }
}
解释
  • ParseIntPipe:这是一个内置的管道,用于将参数转换为整数类型。如果转换失败,将抛出一个 BadRequestException

2. 测试效果

正常请求:
请添加图片描述

我们发现成功响应了请求param的值还有值的类型

异常请求:
请添加图片描述
我们换成abc后发生报错,值的类型不匹配

目前我们就简单使用了管道帮我们进行数据验证
Nest 配有九个开箱即用的管道:

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

使用自定义的全局管道

1. 创建自定义验证管道

src\common\pipes 下创建一个自定义验证管道 validation.pipe.ts

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException, Type } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToInstance } from 'class-transformer';

@Injectable()
export class ValidationPipe implements PipeTransform<any> {
  async transform(value: any, { metatype }: ArgumentMetadata) {
    console.log(metatype)
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToInstance(metatype, value);
    const errors = await validate(object);
    if (errors.length > 0) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }

  private toValidate(metatype: Type): boolean {
    const types = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype as any);
  }
}
解释
  • validate:从 class-validator 导入,用于验证对象。
  • metatype 会自动匹配请求中使用的DTO(数据传输对象),如果没有使用DTO,或者DTO对象在toValidate存在就返回值
  • plainToInstance:从 class-transformer 导入,用于将普通对象转换为类实例,如果值与metatype匹配不上直接抛出异常
  • transform 方法:将传入的数据转换为类实例并进行验证。
  • toValidate 方法:检查元类型是否需要验证。

2. 全局挂载验证管道

我们在 main.ts 中全局挂载自定义验证管道。

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './common/filter/http-exception.filter';
import { ValidationPipe } from './common/pipes/validation.pipe';
require('dotenv').config();


async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  app.useGlobalPipes(new ValidationPipe());

  await app.listen(3000);
}
bootstrap();

3. 使用 DTO 进行验证

我们在src/dto/app.dto.ts下创建两个 DTO,RegisterDtoLoginDto,用于用户注册和登录。

import { IsString, MinLength, MaxLength } from 'class-validator';

export class RegisterDto {
  @IsString()
  @MinLength(2)
  @MaxLength(20)
  username: string;

  @IsString()
  @MinLength(6)
  password: string;
}

export class LoginDto {
  @IsString()
  @MinLength(2)
  @MaxLength(20)
  username: string;

  @IsString()
  @MinLength(6)
  password: string;
}

4. 修改控制器

我们修改 UsersController,使用 DTO 进行数据验证。

import { Controller, Post, Body, Res, HttpException, HttpStatus } from '@nestjs/common';
import { UsersService } from './users.service';
import { RegisterDto, LoginDto } from './dto/app.dto';
import * as jwt from 'jsonwebtoken';
import { Response } from 'express';

@Controller('users')
export class UsersController {
  constructor(private readonly userService: UsersService) {}

  @Post('register')
  register(@Body() registerDto: RegisterDto, @Res() res: Response) {
    const { username, password } = registerDto;
    try {
      const result = this.userService.register(username, password);
      res.status(HttpStatus.CREATED).send({ result, message: '注册成功' });
    } catch (e) {
      throw new HttpException(e.message, HttpStatus.UNAUTHORIZED);
    }
  }

  @Post('login')
  login(@Body() loginDto: LoginDto, @Res() res: Response) {
    const { username, password } = loginDto;
    try {
      const isLogin = this.userService.login(username, password);
      const jwtToken = jwt.sign({ username }, process.env.JWT_SECRET, { expiresIn: '1h' });
      res.status(HttpStatus.OK).send({ result: isLogin, message: '登陆成功', token: jwtToken });
    } catch (e) {
      throw new HttpException(e.message, HttpStatus.UNAUTHORIZED);
    }
  }
}

5. 测试效果

注册:
请添加图片描述

正常登录:
请添加图片描述
异常登录:
请添加图片描述

当我们发送注册请求时,如果传入的数据不符合 DTO 中的验证规则,将会抛出 BadRequestException 并返回验证失败的消息。

结论

通过以上步骤,我们成功地在 Nest.js 应用中添加并使用了自定义验证管道,实现了数据验证和转换的功能。希望这篇博客能帮助你更好地理解和使用 Nest.js 中的管道功能。

在下一个博客中,我们将进一步探讨 Nest.js 的其他功能,敬请期待。

如果各位技术大佬有任何问题或建议,欢迎在评论区留言。

感谢阅读!

  • 22
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值