欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

NestJS使用class-validator進行數(shù)據(jù)驗證

 更新時間:2024年11月06日 09:28:45   作者:樂聞x  
本文將通過詳細的步驟和實戰(zhàn)技巧,帶大家掌握如何在NestJS中使用class-validator進行數(shù)據(jù)驗證,以及11條實戰(zhàn)中常用的驗證技巧,感興趣的可以了解下

前言

在現(xiàn)代Web開發(fā)中,數(shù)據(jù)驗證是必不可少的一環(huán),它不僅能夠確保數(shù)據(jù)的準確性,還能提高系統(tǒng)的安全性。在使用NestJS框架進行項目開發(fā)時,class-validator與class-transformer這兩個庫為我們提供了方便的數(shù)據(jù)驗證解決方案。

本文將通過詳細的步驟和實戰(zhàn)技巧,帶大家掌握如何在NestJS中使用class-validator進行數(shù)據(jù)驗證。通過這篇文章,你將能夠學會如何使用class-validator優(yōu)雅的實現(xiàn)數(shù)據(jù)驗證,以及11條實戰(zhàn)中常用的驗證技巧,提高項目的數(shù)據(jù)校驗能力。

使用步驟

第一步:安裝 class-validator 和 class-transformer

要使用 class-validator,需要安裝兩個庫:class-validator 和 class-transformer。

npm install class-validator class-transformer

第二步:創(chuàng)建 DTO(數(shù)據(jù)傳輸對象)

在 NestJS 中,通常使用 DTO(Data Transfer Object)來定義請求數(shù)據(jù)的結構。首先,需要創(chuàng)建一個用于用戶注冊的 DTO 類,并使用 class-validator 的裝飾器來定義驗證規(guī)則。

// src/user/dto/create-user.dto.ts
import { IsString, IsEmail, IsNotEmpty, Length } from 'class-validator';

export class CreateUserDto {
  @IsString()
  @IsNotEmpty()
  @Length(4, 20)
  username: string;

  @IsEmail()
  email: string;

  @IsString()
  @IsNotEmpty()
  @Length(8, 40)
  password: string;
}

在這個 DTO 中,定義了三個字段:username、email 和 password,并使用 class-validator 的裝飾器指定了驗證規(guī)則。

第三步:使用管道驗證數(shù)據(jù)

接下來,需要在控制器中使用 DTO,并通過 NestJS 的管道(Pipes)來驗證傳入的數(shù)據(jù)。

// src/user/user.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';

@Controller('user')
export class UserController {
  @Post('register')
  async register(@Body() createUserDto: CreateUserDto) {
    // 處理注冊邏輯
    return { message: 'User registered successfully', data: createUserDto };
  }
}

在這個例子中,在 register 方法中使用了 @Body() 裝飾器來獲取請求體,并傳入了 CreateUserDto。NestJS 會自動驗證該 DTO,如果驗證失敗,將拋出異常并返回適當?shù)腻e誤響應。

第四步:全局啟用驗證管道

為了更方便地管理,可以全局啟用驗證管道,這樣所有的 DTO 驗證都會自動進行。

// src/main.ts
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

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

bootstrap();

在 main.ts 文件中,使用 ValidationPipe 全局啟用了驗證管道。這樣一來,無論在哪個控制器中使用 DTO,NestJS 都會自動進行數(shù)據(jù)驗證。當然也可以僅對某些控制器開啟驗證管道,詳情參考下方實戰(zhàn)技巧。

實戰(zhàn)使用技巧

1. 局部驗證管道

可以為特定的路由或控制器方法配置驗證管道,而無需全局啟用。這樣可以在不同的場景下靈活使用不同的驗證規(guī)則。

import { Controller, Post, Body, UsePipes, ValidationPipe } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';

@Controller('user')
export class UserController {
  @Post('register')
  @UsePipes(new ValidationPipe({
    transform: true,
    whitelist: true,
    forbidNonWhitelisted: true,
  }))
  async register(@Body() createUserDto: CreateUserDto) {
    // 處理注冊邏輯
    return { message: 'User registered successfully', data: createUserDto };
  }
}

2. 自定義錯誤消息

class-validator 允許為每個驗證規(guī)則定義自定義錯誤消息。例如:

import { IsString, IsNotEmpty, Length, IsEmail } from 'class-validator';

export class CreateUserDto {
  @IsString({ message: '用戶名必須是字符串' })
  @IsNotEmpty({ message: '用戶名不能為空' })
  @Length(4, 20, { message: '用戶名長度必須在4到20個字符之間' })
  username: string;

  @IsEmail({}, { message: '郵箱格式不正確' })
  email: string;
  
  @IsString({ message: '密碼必須是字符串' })
  @IsNotEmpty({ message: '密碼不能為空' })
  @Length(8, 40, { message: '密碼長度必須在8到40個字符之間' })
  password: string;
}

3. 嵌套對象驗證

如果 DTO 中包含嵌套對象,可以使用 @ValidateNested() 裝飾器進行驗證。例如:

import { Type } from 'class-transformer';
import { ValidateNested, IsString, IsNotEmpty } from 'class-validator';

class AddressDto {
  @IsString()
  @IsNotEmpty()
  street: string;

  @IsString()
  @IsNotEmpty()
  city: string;
}

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

  @ValidateNested()
  @Type(() => AddressDto)
  address: AddressDto;
}

4. 組合驗證裝飾器

有時可能需要將多個驗證規(guī)則組合在一起,這時可以使用 @ValidatorConstraint() 來創(chuàng)建自定義驗證裝飾器。例如:

判斷數(shù)據(jù)庫中是否已經(jīng)存在用戶名

import { registerDecorator, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator';

@ValidatorConstraint({ async: false })
export class IsUsernameUniqueConstraint implements ValidatorConstraintInterface {
  validate(username: any) {
    // 這里可以添加驗證邏輯,例如查詢數(shù)據(jù)庫
    return true; // 如果驗證通過返回 true
  }
}

export function IsUsernameUnique(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      constraints: [],
      validator: IsUsernameUniqueConstraint,
    });
  };
}

// 使用自定義裝飾器
export class CreateUserDto {
  @IsUsernameUnique({ message: '用戶名已存在' })
  username: string;
}

2.驗證密碼強度

import { registerDecorator, ValidationOptions, ValidationArguments } from 'class-validator';
export function IsStrongPassword(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      name: 'isStrongPassword',
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      validator: {
        validate(value: any, args: ValidationArguments) {
          return /(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}/.test(value);
        },
        defaultMessage(args: ValidationArguments) {
          return '密碼必須包含大小寫字母、數(shù)字和特殊字符,并且至少8個字符長';
        },
      },
    });
  };
}
export class ChangePasswordDto {
  @IsStrongPassword({ message: '密碼不符合強度要求' })
  newPassword: string;
}

3.條件驗證

根據(jù)條件進行驗證,可以使用 @ValidateIf 裝飾器。

import { ValidateIf, IsNotEmpty, IsEmail } from 'class-validator';
export class UpdateUserDto {
  @IsEmail()
  email: string;
  @ValidateIf(o => o.email)
  @IsNotEmpty({ message: '新郵件地址不能為空' })
  newEmail: string;
}

4.使用 @Matches 進行正則表達式驗證

使用 @Matches 裝飾器,可以驗證字符串是否與指定的正則表達式匹配。

import { Matches } from 'class-validator';
export class ChangePasswordDto {
  @Matches(/(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}/, { message: '密碼必須包含大小寫字母、數(shù)字和特殊字符,并且至少8個字符長' })
  newPassword: string;
}

5.全局驗證選項

全局啟用驗證管道時,可以配置全局驗證選項,比如剝離非白名單字段、自動轉換類型等。

// src/main.ts
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe({
    whitelist: true, // 剝離非白名單字段
    forbidNonWhitelisted: true, // 禁止非白名單字段
    transform: true, // 自動轉換類型
  }));
  await app.listen(3000);
}
bootstrap();

6.動態(tài)驗證消息

有時可能需要根據(jù)具體的驗證條件動態(tài)生成錯誤消息,可以使用 ValidationArguments 來實現(xiàn)。

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

export class CreateUserDto {
  @IsString()
  @MinLength(4, {
    message: (args: ValidationArguments) => {
      return `用戶名太短了,至少需要 ${args.constraints[0]} 個字符`;
    },
  })
  username: string;
}

7.@Validate 自定義驗證邏輯

如果內置裝飾器無法滿足需求,可以使用 @Validate 裝飾器添加自定義驗證邏輯。

import { Validate, ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';

@ValidatorConstraint({ name: 'customText', async: false })
class CustomTextConstraint implements ValidatorConstraintInterface {
  validate(text: string, args: ValidationArguments) {
    return text.startsWith('prefix_'); // 任何自定義邏輯
  }

  defaultMessage(args: ValidationArguments) {
    return '文本 ($value) 必須以 "prefix_" 開頭';
  }
}

export class CustomTextDto {
  @Validate(CustomTextConstraint)
  customText: string;
}

8.屬性分組驗證

通過分組,可以在不同情境下驗證不同的字段。比如在創(chuàng)建和更新時可能需要驗證不同的字段。

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

export class CreateUserDto {
  @IsString()
  @IsNotEmpty({ groups: ['create'] })
  username: string;

  @IsString()
  @IsNotEmpty({ groups: ['create', 'update'] })
  password: string;
}

// 使用時指定組
import { ValidationPipe } from '@nestjs/common';

const createUserValidationPipe = new ValidationPipe({ groups: ['create'] });
const updateUserValidationPipe = new ValidationPipe({ groups: ['update'] });

在控制器中使用不同的管道進行驗證:
import { Controller, Post, Put, Body, UsePipes } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { createUserValidationPipe, updateUserValidationPipe } from './validation-pipes';

@Controller('user')
export class UserController {
  @Post('create')
  @UsePipes(createUserValidationPipe)
  async createUser(@Body() createUserDto: CreateUserDto) {
    // 處理創(chuàng)建用戶邏輯
    return { message: 'User created successfully', data: createUserDto };
  }

  @Put('update')
  @UsePipes(updateUserValidationPipe)
  async updateUser(@Body() updateUserDto: CreateUserDto) {
    // 處理更新用戶邏輯
    return { message: 'User updated successfully', data: updateUserDto };
  }
}

9.僅執(zhí)行部分屬性驗證

有時可能需要只驗證對象的一部分屬性,可以使用 PartialType 來實現(xiàn)。

import { PartialType } from '@nestjs/mapped-types';

export class UpdateUserDto extends PartialType(CreateUserDto) {}
//以下是如何在控制器中使用 UpdateUserDto。
// src/user/user.controller.ts
import { Controller, Post, Put, Body, Param } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
@Controller('user')
export class UserController {
  @Post('create')
  async createUser(@Body() createUserDto: CreateUserDto) {
    // 處理創(chuàng)建用戶邏輯
    return { message: 'User created successfully', data: createUserDto };
  }
  @Put('update/:id')
  async updateUser(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    // 處理更新用戶邏輯
    return { message: 'User updated successfully', data: updateUserDto };
  }
}

在這個示例中,UpdateUserDto 繼承自 PartialType(CreateUserDto),這意味著 UpdateUserDto 包含 CreateUserDto 中的所有屬性,但這些屬性都是可選的。這在更新操作中非常有用,因為我們可能只想提供那些需要更新的字段,而不是所有字段。

10.驗證消息的國際化

通過使用自定義驗證裝飾器和消息生成函數(shù),可以實現(xiàn)驗證消息的國際化。

import { IsString, IsNotEmpty, Length, ValidationArguments } from 'class-validator';
import { i18n } from 'i18next'; // 假設在項目中使用 i18n

export class CreateUserDto {
  @IsString()
  @IsNotEmpty({ message: (args: ValidationArguments) => i18n.t('validation.usernameRequired') })
  @Length(4, 20, { message: (args: ValidationArguments) => i18n.t('validation.usernameLength', { min: 4, max: 20 }) })
  username: string;
}

總結

使用 class-validator 結合 NestJS,可以讓輕松地在應用中進行數(shù)據(jù)驗證,不僅提高了代碼的可讀性,還保證了數(shù)據(jù)的準確性和安全性。

以上就是NestJS使用class-validator進行數(shù)據(jù)驗證的詳細內容,更多關于NestJS數(shù)據(jù)驗證的資料請關注腳本之家其它相關文章!

相關文章

最新評論