第十五章 Nest Pipe(内置及自定义)

NestJS的Pipe是一个用于数据转换和验证的特殊装饰器。Pipe可以应用于控制器(Controller)的处理方法(Handler)和中间件(Middleware),用于处理传入的数据。它可以用来转换和验证数据,确保数据的有效性和一致性。

内置的 Pipe 是指在使用 NestJS 框架时,已经预定义好的一些管道,用于验证和转换传入的数据。

  • ValidationPipe(验证管道):用于验证传入的数据是否符合指定的规则,可以使用 class-validator 和 class-transformer 库来实现验证和转换。
  • ParseIntPipe(整数转换管道):用于将传入的字符串转换为整数。
  • ParseBoolPipe(布尔值转换管道):用于将传入的字符串转换为布尔值。
  • ParseArrayPipe(数组转换管道):用于将传入的字符串转换为数组。
  • ParseUUIDPipe(UUID 转换管道):用于将传入的字符串转换为 UUID。
  • DefaultValuePipe(默认值管道):用于在传入的参数不存在时,给参数设置一个默认值。
  • ParseEnumPipe(枚举转换管道):用于将传入的字符串转换为枚举类型。
  • ParseFloatPipe(浮点数转换管道):用于将传入的字符串转换为浮点数。
  • ParseFilePipe(文件转换管道):用于将传入的文件转换为上传的文件对象。

接下来我们测试一下内置 Pipe 的功能:
创建项目

nest new pipe -p npm

1719120039619.png
修改 app.controller.ts 可以看到这个接口默认接收test的字符串参数

import { Controller, Get, Query } from '@nestjs/common';
import { AppService } from './app.service';

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

  @Get()
  getHello(@Query('test') test: string): string {
    return test;
  }
}

1、ParseIntPipe

我们可以使用ParseIntPipe 将接收的字符串参数转为整数:

import { Controller, Get, ParseIntPipe, Query } from '@nestjs/common';
import { AppService } from './app.service';

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

  @Get()
  getHello(@Query('test', ParseIntPipe) test: string): string {
    return test+10;
  }
}

访问接口 http://localhost:3000/?test=100 可以看到参数test传入 100 变成了 110
1719120853656.png
且当我们传入的参数不能转为init时 则会报错 例如下面 访问 http://localhost:3000/?test=ww
1719120993724.png
这个返回的报错 我们也可以自定义 但是这种方式需要使用new XxxPipe 的方式 例如指定状态码为404

import { Controller, Get, HttpStatus, ParseIntPipe, Query } from '@nestjs/common';
import { AppService } from './app.service';

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

  @Get()
  getHello(@Query('test', new ParseIntPipe({
    errorHttpStatusCode: HttpStatus.NOT_FOUND,
  })) test: string): string {
    return test + 10;
  }
}

1719121317498.png
同时也可以抛出异常再进行处理

import { Controller, Get, HttpException, HttpStatus, ParseIntPipe, Query } from '@nestjs/common';
import { AppService } from './app.service';

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

  @Get()
  getHello(@Query('test', new ParseIntPipe({
    errorHttpStatusCode: HttpStatus.NOT_FOUND,
    exceptionFactory(error) {
      console.log(error);
      throw new HttpException('测试报错' + error, HttpStatus.NOT_IMPLEMENTED)

    },
  })) test: string): string {
    return test + 10;
  }
}

1719121515372.png

2、ParseFloatPipe

ParseFloatPipe 的作用是将参数转为float 类型
我们新建一个接口: test

import { Controller, Get, HttpException, HttpStatus, ParseFloatPipe, ParseIntPipe, Query } from '@nestjs/common';
import { AppService } from './app.service';

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

  @Get()
  getHello(@Query('test', new ParseIntPipe({
    errorHttpStatusCode: HttpStatus.NOT_FOUND,
    exceptionFactory(error) {
      console.log(error);
      throw new HttpException('测试报错' + error, HttpStatus.NOT_IMPLEMENTED)

    },
  })) test: string): string {
    return test + 10;
  }

  @Get('test')
  getTest(@Query('test', ParseFloatPipe) test: number) {
    return test + 10;
  }
}

访问 http://localhost:3000/test?test=10.4
1719122081715.png
同样可以new ParseFloatPipe 的形式,传入 errorHttpStatusCode 和 exceptionFactory

3、ParseBoolPipe

用于将传入的字符串转换为布尔值。

@Get('boolean')
  getBoolean(@Query('test') test: boolean) {
    return test;
  }

访问 http://localhost:3000/boolean?test=false
1719122405754.png

4、ParseArrayPipe

用于将传入的字符串转换为数组。

@Get('array')
  getArray(@Query('test', ParseArrayPipe) test: number[]) {
    return test.reduce((pre, cur) => pre + cur, 0);
  }

保存代码可以发现报错了 提示需要class-validator 这个包
1719122693022.pngclass-class-class-validator 允许使用基于装饰器和非装饰器的验证。 内部使用 validator.js 来执行验证。

pnpm install class-validator

安装之后启动 发现还是报错 缺少 class-transformer
class-transformer 允许您将普通对象转换为类的某个实例,反之亦然。 此外,它还允许根据条件序列化/反序列化对象。 这个工具在前端和后端都非常有用。
1719123624634.png

pnpm install class-transformer 

访问 http://localhost:3000/array?test=1,2,3,4
1719123834101.png
可以发现 每一项都提取出来了但是类型还是string 没有转换成number类型
此时需要 new XxxPipe 的方式传入参数:

@Get('array')
  getArray(@Query('test', new ParseArrayPipe({
    items: Number,
  })) test: number[]) {
    return test.reduce((pre, cur) => pre + cur, 0);
  }

再次访问 http://localhost:3000/array?test=1,2,3,4
1719123963798.png
同时还可以指定传入时的分割符: separator: ‘/’,

@Get('array')
  getArray(@Query('test', new ParseArrayPipe({
    items: Number,
    separator: '/',
  })) test: number[]) {
    return test.reduce((pre, cur) => pre + cur, 0);
  }

访问 http://localhost:3000/array?test=1/2/3/4
1719124196570.png
当我们没有传入参数的时候会报错:
image.png
我们可以通过设置 optional 来实现不传参数不报错

  @Get('array')
  getArray(@Query('test', new ParseArrayPipe({
    items: Number,
    separator: '/',
    optional: true,
  })) test: number[]) {
    return test
  }

1719124324325.png

5、ParseEnumPipe

用于将传入的字符串转换为枚举类型。

import { Controller, Get, HttpException, HttpStatus, ParseArrayPipe, ParseEnumPipe, ParseFloatPipe, ParseIntPipe, Query } from '@nestjs/common';
import { AppService } from './app.service';

enum TestEnum {
  A = 'A111',
  B = 'B111',
}

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

  @Get()
  getHello(@Query('test', new ParseIntPipe({
    errorHttpStatusCode: HttpStatus.NOT_FOUND,
    exceptionFactory(error) {
      console.log(error);
      throw new HttpException('测试报错' + error, HttpStatus.NOT_IMPLEMENTED)

    },
  })) test: string): string {
    return test + 10;
  }

  @Get('test')
  getTest(@Query('test', ParseFloatPipe) test: number) {
    return test + 10;
  }

  @Get('boolean')
  getBoolean(@Query('test') test: boolean) {
    return test;
  }


  @Get('array')
  getArray(@Query('test', new ParseArrayPipe({
    items: Number,
    separator: '/',
    optional: true,
  })) test: number[]) {
    return test
  }

  @Get('enum/:test')
  getEnum(@Query('test', new ParseEnumPipe(TestEnum)) test: TestEnum) {
    return test
  }
}

访问 http://localhost:3000/enum/111
1719126381961.png
当我们传的参数不是枚举定义的类型时会报错
访问 http://localhost:3000/enum/555
1719126484884.png

6、 ParseUUIDPipe

用于将传入的字符串转换为 UUID。在参数里,可以用 ParseUUIDPipe 来校验是否是 UUID
首先我们安装一下 uuid 用于生成uuid

pnpm install uuid

接着我们实现2个接口 getUuid getUuid2

import { Controller, Get, HttpException, HttpStatus, Param, ParseArrayPipe, ParseEnumPipe, ParseFloatPipe, ParseIntPipe, ParseUUIDPipe, Query } from '@nestjs/common';
import { AppService } from './app.service';

const uuid = require('uuid');

enum TestEnum {
  A = '111',
  B = '222',
  C = '333'
}

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

  @Get()
  getHello(@Query('test', new ParseIntPipe({
    errorHttpStatusCode: HttpStatus.NOT_FOUND,
    exceptionFactory(error) {
      console.log(error);
      throw new HttpException('测试报错' + error, HttpStatus.NOT_IMPLEMENTED)

    },
  })) test: string): string {
    return test + 10;
  }

  @Get('test')
  getTest(@Query('test', ParseFloatPipe) test: number) {
    return test + 10;
  }

  @Get('boolean')
  getBoolean(@Query('test') test: boolean) {
    return test;
  }


  @Get('array')
  getArray(@Query('test', new ParseArrayPipe({
    items: Number,
    separator: '/',
    optional: true,
  })) test: number[]) {
    return test
  }

  @Get('enum/:test')
  getEnum(@Param('test', new ParseEnumPipe(TestEnum)) e: TestEnum) {
    return e
  }

  @Get('uuid')
  getUuid() {
    return uuid.v4()
  }

  @Get('uuid/:uuid')
  getUuid2(@Param('uuid', new ParseUUIDPipe) uuid: string) {
    return uuid
  }
}

访问 http://localhost:3000/uuid 获取uuid
1719127289811.png
接着访问 http://localhost:3000/uuid/0a5c5ce9-22ff-4091-85ef-523fcb64223c 可以看到正常访问
1719127352975.png
但是如果参数不是正常的uuid那么会报错
http://localhost:3000/uuid/xxx
1719127399773.png

7、DefaultValuePipe

用于在传入的参数不存在时,给参数设置一个默认值。
创建一个接口:

@Get('default')
  getDefault(@Query('test', new DefaultValuePipe('test')) test: string) {
    return test
  }

当我们没传参数的时候 会使用默认值test http://localhost:3000/default
1719127714732.png
当我们传参数之后将会返回参数 例如 http://localhost:3000/default?test=123456
1719127771860.png


8、自定义Pipe

首先创建一个 pipe:

nest g pipe www --flat --no-spec

www.pipe.ts:

import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';

@Injectable()
export class WwwPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    console.log(value,metadata);
    
    return 'www';
  }
}

增加接口:

  @Get('www')
  getWww(@Query('test', WwwPipe) test: string, @Query('test2', WwwPipe) test2: string) {
    return test + test2
  }

浏览器访问 http://localhost:3000/www?test=1234&test2=1
1719128253615.png
这就是Pipe返回的值
1719128288386.png
控制台打印了 value 就是 query、param 的值,而 metadata 里包含 type、metatype、data
1719129484281.png
1719129507003.png
type 就是 @Query、@Param、@Body 装饰器,或者自定义装饰器
metatype 是参数的 ts 类型
data 参数值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/777045.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软通动力子公司鸿湖万联最新成果SwanLink AI亮相世界人工智能大会

7月4日,2024世界人工智能大会暨人工智能全球治理高级别会议(WAIC 2024)在上海拉开帷幕,软通动力董事长兼首席执行官刘天文受邀出席开幕式。其间,软通动力携子公司鸿湖万联深度参与到大会各项活动中,并全面展…

制作Ai 数字人和数字人带货全面拆解复盘

看了后不用再花高价钱去买怎么制作数字人 .数字人带货的相关教程了 市面上基本都是通过这几个方法制作的数字人 超级详细 值得注意的是 拆解的太详细 仅供正规个人用途哦 请勿用于任何非法操作 否则 就不用接着往下看了 点击获取完整版资料

基于图像处理的滑块验证码匹配技术

滑块验证码是一种常见的验证码形式,通过拖动滑块与背景图像中的缺口进行匹配,验证用户是否为真人。本文将详细介绍基于图像处理的滑块验证码匹配技术,并提供优化代码以提高滑块位置偏移量的准确度,尤其是在背景图滑块阴影较浅的情…

R语言fastshap包进行支持向量机shap可视化分析

1995年VAPINK 等人在统计学习理论的基础上提出了一种模式识别的新方法—支持向量机 。它根据有限的样本信息在模型的复杂性和学习能力之间寻求一种最佳折衷。 以期获得最好的泛化能力.支持向量机的理论基础决定了它最终求得的是全局最优值而不是局部极小值,从而也保证了它对未知…

在AvaotaA1全志T527开发板上使用AvaotaOS 部署 Docker 服务

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 准备…

Maven 分模块设计与开发 继承

介绍 在 Maven 中进行分模块设计(multi-module project),可以帮助将一个大型项目分解为更小、更易管理的模块。这种设计方式有助于提高项目的可维护性、复用性和团队协作效率。 继承关系 目录结构 引入父Maven 父坐标 在子项目中引入父亲…

雷电模拟器报错remount of the / superblock failed: Permission denied remount failed

报错截图 解决方法 打开设置 设置配置system.vmdk可写入 解决

【Nginx】docker运行Nginx及配置

Nginx镜像的获取 直接从Docker Hub拉取Nginx镜像通过Dockerfile构建Nginx镜像后拉取 二者区别 主要区别在于定制化程度和构建过程的控制: 直接拉取Nginx镜像: 简便性:直接使用docker pull nginx命令可以快速拉取官方的Nginx镜像。这个过程…

可变参数 Collections 不可变集合 Stream流

目录 1.可变参数: 2.Collections: 3.不可变集合: 4.Stream流: 1、什么是流 2、如何生成流 1.单列集合获取Stream流 2.双列集合获取Stream流 3.数组获取Stream流: 4.一堆零散数据: Stream接口中的静态方法 3.Stream流的…

使用友元函数访问私有数据

如果在本类以外的其他地方定义了一个函数(这个函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数),在类体中用friend对其进行声明,此函数就称为本类的友元函数。友元函数可以访问这个类中的私有成员。正如…

数据结构(3.5)——队列的顺序实现

队列的顺序实现 #define MaxSize 10//定义队列中元素的最大个数 typedef struct {int data[MaxSize];//用静态数组存放队列元素int front, rear;//队头指针和队尾指针 } SqQueue;void testQueue() {SqQueue Q;//声明一个队列(顺序存储) } 队列的初始化操作和判空 //初始化队…

昇思25天学习打卡营第11天 | LLM原理和实践:基于MindSpore实现BERT对话情绪识别

1. 基于MindSpore实现BERT对话情绪识别 1.1 环境配置 # 实验环境已经预装了mindspore2.2.14,如需更换mindspore版本,可更改下面mindspore的版本号 !pip uninstall mindspore -y !pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore2.2…

Rust变量绑定

变量绑定 Rust 通过静态类型确保类型安全。变量绑定可以在声明时说明类型,不过在多数情况下,编译器能够从上下文推导出变量的类型,从而大大减少了类型说明的工作。 使用 let 绑定操作可以将值(比如字面量)绑定&#…

ESP32 通过蓝牙显示歌词代码示例

通过蓝牙协议播放音乐,有的时候需要显示歌词,这里就是a2dp库获取了歌词 值得注意的是要想正确获取到歌词,必须打开各种播放器的字幕(歌词)开关 本项目用了三个开源库 a2dp,tft_espi,xfont. a2dp &#x…

ITWin Capture Modeler:打造卓越的软件模型的终极工具

在软件开发和设计领域,寻找一款高效且功能强大的软件模型工具是每个开发人员的追求。而经过多年的实践和尝试,我终于找到了一款令人印象深刻的工具——ITWin Capture Modeler。它不仅具备出色的功能和灵活性,而且能够极大地提高开发效率和质量…

计算机网络体系结构详解:协议与分层

在学习计算机网络时,理解网络协议与分层体系结构是至关重要的。本文将详细介绍这些概念,帮助基础小白快速入门。 1. 什么是网络协议 网络协议是计算机网络中用于数据交换的规则和标准。这些规则规定了数据格式、时序以及发送和接收数据时的动作。网络协…

数学不好能搞人工智能吗?

很遗憾,不能。 人工智能(AI)实际上是一个将数学、算法理论和工程实践紧密结合的领域。AI 扒开来看就是算法,也就是数学、概率论、统计学、各种数学理论的体现。 新的时代,程序员想要跨入 AI 之门,只要稍微…

FTP、http 、tcp

HTTP VS FTP HTTP :HyperText Transfer Protocol 超文本传输协议,是基于TCP协议 FTP: File Transfer Protocol 文件传输协议, 基于TCP协议, 基于UDP协议的FTP 叫做 TFTP HTTP 协议 通过一个SOCKET连接传输依次会话数…

奇舞周刊第532期:奇舞团生日快乐~

时光荏苒,岁月如歌,转眼间,奇舞团13岁啦🎂🎂🎂《奇舞周刊》也陪伴大家来到了第532期。👏👏 致敬每一位读者和创作者,是你们的热情、陪伴和鼓励,让我们不断前进…

【Linux】:进程创建与终止

朋友们、伙计们,我们又见面了,本期来给大家解读一下有关Linux程序地址空间的相关知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏:C语言:从…