国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

NestJs 管道(Pipe)

這篇具有很好參考價值的文章主要介紹了NestJs 管道(Pipe)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

??Hi~ 大家好,我是小鑫同學,資深 IT 從業(yè)者,InfoQ 的簽約作者,擅長前端開發(fā)并在這一領(lǐng)域有多年的經(jīng)驗,致力于分享我在技術(shù)方面的見解和心得

??技術(shù)&代碼分享

  • 我在 94Code 總結(jié)技術(shù)學習;
  • 我在 1024Code 在線編寫代碼;
  • 我在 Github 參與開源學習;

??推薦幾個好用的工具

  • var-conv 適用于VSCode IDE的代碼變量名稱快速轉(zhuǎn)換工具
  • generator-vite-plugin 快速生成Vite插件模板項目
  • generator-babel-plugin 快速生成Babel插件模板項目

進入正題

Nestjs 中管道是具有 @Injectable() 裝飾器且已實現(xiàn) PipeTransform 接口的類。

管道(Pipe)的作用

管道(Pipe)作用在每個控制器的處理方法上,也就是當每一個請求被路由到具體的控制器的方法后會先通過管道(Pipe)對傳入的請求參數(shù)進行 轉(zhuǎn)換驗證,保證數(shù)據(jù)在被正式處理前是完全合法的。

管道(Pipe)的使用

Nestjs 中內(nèi)置了下列的9個管道,利用這些管道可以輕松的驗證路由參數(shù)、查詢參數(shù)和請求正文是否合法,下面通過兩個例子一起看一下管道的使用。

ParseIntPipe ParseFloatPipe
ParseBoolPipe ParseArrayPipe
ParseUUIDPipe ParseEnumPipe
ParseFilePipe
DefaultValuePipe ValidationPipe

findUserById 是用來根據(jù)用戶 ID 獲取用戶信息的處理函數(shù),期望id由客戶端傳來的必須是數(shù)字類型。

@Controller('users')
export class UsersController {
  @Get(':id')
  findUserById(@Param('id') id: number): string {
    return `The ID of this user is ${id}`;
  }
}

現(xiàn)在由于缺少對路由參數(shù)類型的校驗,此時客戶端在傳遞非數(shù)字類型的ID時并不會收到合理的提醒,這樣很容易造成服務(wù)端業(yè)務(wù)邏輯的異常,有入庫的操作的話還會造成垃圾數(shù)據(jù)。所以可將 ParseIntPipe 管道類直接添加到 @Param() 裝飾器的第二位參數(shù),如下圖:

@Controller('users')
export class UsersController {
  @Get(':id')
  findUserById(@Param('id', ParseIntPipe) id: number): string {
    return `The ID of this user is ${id}`;
  }
}

增加 ParseIntPipe 管道的限制后,當客戶端再次傳遞非數(shù)字類型的ID時就會收到對應(yīng)的提示。

NestJs 管道(Pipe)

上面的例子中使用了管道類而非管道的實例是因為 Nestjs 基于 IoC 的設(shè)計在框架內(nèi)部可以自動對類進行實例化操作,管道同時也支持通過構(gòu)造函數(shù)傳遞選項的方式自定義內(nèi)置管道的行為。

下面這個 findUserByUUID 函數(shù)中使用的 ParseUUIDPipe 管道默認情況下是支持接收不同版本的 UUID 的,但在例子中我們限制只可以接收 v5 版本的 UUID,就需要實例化 ParseUUIDPipe 并在構(gòu)造函數(shù)中指定具體的 version 。

@Get(':uuid')
findUserByUUID(
    @Param('uuid', new ParseUUIDPipe({ version: '5' })) uuid: string,
): string {
    return `The UUID of this user is ${uuid}`;
}

NestJs 管道(Pipe)

NestJs 管道(Pipe)

基于 schema 的驗證

createUser 處理函數(shù)中要求客戶端傳遞一份包含 nameagegender 的數(shù)據(jù),對于這種復(fù)雜的數(shù)據(jù)結(jié)構(gòu)來說可以引入 schema (前端表單校驗常用技術(shù))來配合自定義管道實現(xiàn)。

export class CreateUserDto {
  name: string;
  age: number;
  gender: boolean;
}

@Post()
createUser(@Body() createUserDto: CreateUserDto): string {
  return `${createUserDto.name} is the 100th user`;
}

首先需要引入 joi 模塊和 @types/joi 模塊,使用 ES 模塊導入的方式導入 joi 時需要在 tsconfig.json 中啟用 esModuleInterop 選項。接著使用 Joi 模塊將 CreateUserDto 中的三個屬性均設(shè)置為必填項。

import Joi from 'joi';

export const createUserSchema = Joi.object({
  name: Joi.string().required(),
  age: Joi.number().required(),
  gender: Joi.bool().required(),
});

定義完 schema 后可以使用 nest g pi joi-validation 創(chuàng)建一個公共的管道,在 transform 函數(shù)中使用已經(jīng)注入的ObjectSchema 對象提供的 validate 函數(shù)對請求參數(shù) value 做驗證,當驗證不通過是拋出合理的異常,反之通過。

@Injectable()
export class JoiValidationPipe implements PipeTransform {
  constructor(private schema: ObjectSchema) {}

  transform(value: any, metadata: ArgumentMetadata) {
    const { error } = this.schema.validate(value);
    if (error) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }
}

這里的管道就需要綁定到 createUser 處理函數(shù)級別了,需要用到 @UsePipes() 裝飾器,并傳入通過 Joi 定義的 schema。

@Post()
@UsePipes(new JoiValidationPipe(createUserSchema))
createUser(@Body() createUserDto: CreateUserDto): string {
  return `${createUserDto.name} is the 100th user`;
}

當客戶端未傳遞其中某一個字段時就會收到如下的提示信息。

NestJs 管道(Pipe)

基于 dto 的驗證

在基于 schema 的驗證中不僅編寫了通用的 joi-validation 管道,還用 Joi 庫編寫了一份和 CreateUserDto 幾乎一樣的 schema 文件,每當 DTO 文件有變更時就需要同步維護 schema 文件。

基于 dto 的驗證就可以利用為已創(chuàng)建的 CreateUserDto 增加驗證相關(guān)的裝飾器并配合通過的管道即可完成,從而可以少維護一份文件,避免不一致造成的問題。

首先執(zhí)行 npm i --save class-validator class-transformer 安裝必要的模塊,接著為 CreateUserDto 增加驗證相關(guān)的裝飾器。

import { IsString, IsNumber, IsBoolean, IsNotEmpty } from 'class-validator';

export class CreateUserDto {
  @IsString()
  @IsNotEmpty()
  name: string;

  @IsNumber()
  @IsNotEmpty()
  age: number;

  @IsBoolean()
  @IsNotEmpty()
  gender: boolean;
}

接著執(zhí)行 nest g pi dto-validation 創(chuàng)建一個公共的管道,在這個管道中需要做這么幾件事情:

  1. 解構(gòu) metadata 參數(shù),獲取請求體參數(shù)的元類型。
  2. 定義私有函數(shù) toValidation,跳過非DTO的類型(非Javascript原類型)。
  3. 使用 plainToInstance 將元類型和請求體參數(shù)轉(zhuǎn)為可驗證的類型對象。
  4. 通過 validate 函數(shù)執(zhí)行校驗,校驗未通過則拋出合理的異常信息。
import {
  ArgumentMetadata,
  BadRequestException,
  Injectable,
  PipeTransform,
} from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToInstance } from 'class-transformer';

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

  /**
   * 當 metatype 所指的參數(shù)的元類型僅為Javascript原生類型的話則跳過校驗,這里只關(guān)注了對定義的DTO的校驗
   */
  private toValidation(metatype: Function): boolean {
    const types: Function[] = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }
}

再接著將 DtoValidationPipe 管道綁定到 createUser 處理方法并作驗證。

@Post()
createUser(
  @Body(new DtoValidationPipe()) createUserDto: CreateUserDto,
): string {
  return `${createUserDto.name} is the 100th user`;
}

NestJs 管道(Pipe)

PS:Nestjs 提供的 ValidationPipe 管道可以完全支持上述兩種驗證方式,我們不必為自定義驗證管道花費時間。

提供默認值

提供默認值可以看做是管道在轉(zhuǎn)換場景的一個體現(xiàn),增加默認值的處理可以使得服務(wù)端的代碼更加的健壯。這里使用到了內(nèi)置的 DefaultValuePipe 管道。

@Get()
findAllUsers(
  @Query('activeOnly', new DefaultValuePipe(false), ParseBoolPipe)
  activeOnly: boolean,
  @Query('page', new DefaultValuePipe(10), ParseIntPipe) page: number,
): string {
  return `This action return all users,request parameters:activeOnly: ${activeOnly},page:${page}`;
}

NestJs 管道(Pipe)

全局管道注冊

除上述管道的注冊位置,還支持全局注冊,注冊方式同全局異常過濾器的注冊,一個是基于 app 實例的注冊,另一個是基礎(chǔ)跟模塊的注冊。

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();
import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_PIPE,
      useClass: ValidationPipe
    }
  ]
})
export class AppModule {}

總結(jié)

以上就是 Nest 中管道類的使用方式,也是保證參數(shù)正常接收、正常入庫的必要手段。


如果看完覺得有收獲,歡迎點贊、評論、分享支持一下。你的支持和肯定,是我堅持寫作的動力~文章來源地址http://www.zghlxwxcb.cn/news/detail-484247.html

到了這里,關(guān)于NestJs 管道(Pipe)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • java.io.IOException: Broken pipe管道斷開

    一、Broken pipe產(chǎn)生原因分析 1.當訪問某個服務(wù)突然服務(wù)器掛了,就會產(chǎn)生Broken pipe; 2.客戶端讀取超時關(guān)閉了連接,這時服務(wù)器往客戶端再寫數(shù)據(jù)就發(fā)生了broken pipe異常! 3.端口沖突,地址已被使用,也會導致Broken pipe 二、方案 1.問題一分析服務(wù)器為什么掛了。 2.問題二使用jp

    2024年02月10日
    瀏覽(19)
  • Linux進程間通信 - 信號(signal) 與 管道(pipe) 與 消息隊列

    Linux進程間通信 - 信號(signal) 與 管道(pipe) 與 消息隊列

    什么是進程間通信,就是進程與進程之間進行通信,互相發(fā)送消息;可以通過 信號 或者 管道 或者 消息隊列 或者 信號量 去通信! 目錄 一、信號 1. 信號簡介? 2. 都有那些信號? 3. 注冊信號的函數(shù) 1). signal 2). sigaction (項目中強烈推薦使用) 4. 信號發(fā)送 1). kill 函數(shù) 2). alarm 函

    2024年02月01日
    瀏覽(19)
  • 【探索Linux】—— 強大的命令行工具 P.14(進程間通信 | 匿名管道 | |進程池 | pipe() 函數(shù) | mkfifo() 函數(shù))

    【探索Linux】—— 強大的命令行工具 P.14(進程間通信 | 匿名管道 | |進程池 | pipe() 函數(shù) | mkfifo() 函數(shù))

    當今計算機系統(tǒng)中,進程間通信扮演著至關(guān)重要的角色。隨著計算機系統(tǒng)的發(fā)展和復(fù)雜性的增加,多個進程之間的協(xié)作變得更加必要和常見。進程間通信使得不同進程能夠共享資源、協(xié)調(diào)工作、傳輸數(shù)據(jù),并實現(xiàn)更加復(fù)雜和強大的功能。本文將深入探討進程間的通信,以及管

    2024年02月05日
    瀏覽(28)
  • 在Python中優(yōu)雅地用多進程:進程池 Pool、管道通信 Pipe、隊列通信 Queue、共享內(nèi)存 Manager Value

    在Python中優(yōu)雅地用多進程:進程池 Pool、管道通信 Pipe、隊列通信 Queue、共享內(nèi)存 Manager Value

    Python 自帶的多進程庫 multiprocessing 可實現(xiàn)多進程。我想用這些短例子示范如何優(yōu)雅地用多線程。中文網(wǎng)絡(luò)上,有些人只是翻譯了舊版的 Python 官網(wǎng)的多進程文檔。而我這篇文章會額外講一講下方加粗部分的內(nèi)容。 創(chuàng)建進程 Process, fork 直接繼承資源,所以初始化更快,spawn 只

    2024年02月16日
    瀏覽(24)
  • 小滿nestjs(第一章 介紹nestjs)

    小滿nestjs(第一章 介紹nestjs)

    視頻課程 小滿nest js 系列_嗶哩嗶哩_bilibili Nestjs 是一個用于構(gòu)建高效可擴展的一個基于Node js 服務(wù)端 應(yīng)用程序開發(fā)框架 并且完全支持typeScript? 結(jié)合了 AOP 面向切面的編程方式 nestjs 還是一個spring MVC 的風格 其中有依賴注入 IOC 控制反轉(zhuǎn) 都是借鑒了Angualr nestjs 的底層代碼運用了

    2024年02月01日
    瀏覽(27)
  • NestJS入門及實戰(zhàn)(一)NestJS入門、RESTful API

    NestJS入門及實戰(zhàn)(一)NestJS入門、RESTful API

    Nest (NestJS) 是一個用于構(gòu)建高效、可擴展的 Node.js 服務(wù)器端應(yīng)用程序的開發(fā)框架 JS 屆的 Spring 框架 支持 TypeScript 語言 構(gòu)建高效可伸縮 裝飾器風格 模塊加載采用依賴注入 IOC 方式 (Spring 與 AngularJS) 配套功能齊備(鑒權(quán)、文檔、微服務(wù)、CLI、Graph QL) 可能Node大家了解最多的后

    2023年04月08日
    瀏覽(17)
  • nestjs筆記

    控制反轉(zhuǎn) IoC 控制反轉(zhuǎn)(Inversion of Control,縮寫為 IoC)是面向?qū)ο缶幊讨械囊环N設(shè)計原則,可以用來降低計算機代碼之間的耦合度。其中最常見的方式叫做依賴注入(Dependency Injection,簡稱DI),還有一種方式叫“依賴查找”(Dependency Lookup)。通過控制反轉(zhuǎn),對象在被創(chuàng)建的

    2024年02月03日
    瀏覽(16)
  • NestJS 基礎(chǔ)概念

    ? 1. Module Module是NestJS 的基本組織單位。 模塊系統(tǒng)基于 Node.js 的 CommonJS 模塊系統(tǒng),但提供了更高級別的抽象和組織方式。通過使用模塊,你可以將應(yīng)用程序拆分成多個獨立且可復(fù)用的部分,每個模塊都負責實現(xiàn)特定的功能或業(yè)務(wù)邏輯。 模塊可以封裝相關(guān)的代碼、配置和依賴

    2024年04月08日
    瀏覽(15)
  • nestjs 裝飾器

    裝飾器是一種特殊的類型聲明,它可以附加在類、方法、屬性、參數(shù)上邊 需開啟tsconfig.json中 \\\"experimentalDecorators\\\":true 生成tsconfig.json文件 2、類裝飾器 2、屬性裝飾器 3、參數(shù)裝飾器 4、方法裝飾器 5、自定義裝飾器 添加配置、安裝依賴

    2024年01月16日
    瀏覽(14)
  • 利用Golang pipe實現(xiàn)遠程交互

    本文介紹Golang pipe,以及在不同場景下的應(yīng)用。 pipe實現(xiàn)從一個進程重定向至另一個進程,它是雙向數(shù)據(jù)通道,用于實現(xiàn)進行間通信。 io.Pipe函數(shù)創(chuàng)建內(nèi)存同步通道,用于連接io.Reader和io.Writer. 本文示例使用環(huán)境為: 在實現(xiàn)遠程交互之前,先看下面簡單示例,演示如何使用io.Pi

    2024年02月02日
    瀏覽(15)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包