You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

NestJS提取请求参数时同步实现验证的方案问询

Solution for Validating DTO with Route Params in NestJS

Hey there, let's fix your issue with validating the BeneficiaryHashIdDto alongside extracting route params. The problem with your current code is that when you pass a specific field name to @Param('beneficiaryId'), you're only binding that single string value to your DTO—so the ValidationPipe can't properly validate the DTO's structure or rules. Here are a few clean ways to solve this:

1. Bind Full Route Params to DTO + Validate

The simplest approach is to let Nest bind all route parameters directly to your DTO, then apply the ValidationPipe to validate the entire DTO.

First, make sure your BeneficiaryHashIdDto uses class-validator decorators to define validation rules:

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

export class BeneficiaryHashIdDto {
  // Add validation rules that match your requirements
  @IsString()
  @IsNotEmpty()
  @Matches(/^[a-f0-9]{32}$/) // Example: Enforce 32-character hex hash format
  beneficiaryId: string;
}

Then update your controller method to bind the full params object to the DTO and validate it:

@Post('beneficiaries/:beneficiaryId/bankDetails') 
@HttpCode(HttpStatus.OK) 
async addBankDetails(
  // Remove the specific field name, let Nest bind all params to the DTO
  @Param(new ValidationPipe({ 
    transform: true, // Convert plain object to DTO instance
    whitelist: true, // Strip any extra fields not defined in the DTO
    abortEarly: false // Return all validation errors at once
  })) 
  beneficiaryHash: BeneficiaryHashIdDto, 
  @Body() body, 
  @Headers() headers
) { 
  // Now beneficiaryHash is fully validated!
  const beneficiary = await this.beneficiaryService.getBeneficiaryIdFromHash(beneficiaryHash, ['beneficiaryId', 'currencyCode', 'countryCode']); 
  // ... rest of your code
}

2. Handle Additional Request Params (clientId, customerId)

Since you mentioned your request includes clientId and customerId, you can extend this pattern to validate those too:

  • If they're route params, add them to BeneficiaryHashIdDto with validation rules.
  • If they're query params, create a separate DTO and use @Query() with a ValidationPipe:
// Example Query DTO
export class RequestQueryDto {
  @IsString()
  @IsNotEmpty()
  clientId: string;

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

// Updated controller method
async addBankDetails(
  @Param(new ValidationPipe({ transform: true, whitelist: true })) 
  beneficiaryHash: BeneficiaryHashIdDto,
  @Query(new ValidationPipe({ transform: true, whitelist: true }))
  query: RequestQueryDto,
  @Body() body, 
  @Headers() headers
) { 
  // Both beneficiaryHash and query are validated now
  const { clientId, customerId } = query;
  // ... rest of your code
}

3. Why This Works

  • transform: true: Tells Nest to convert the plain JavaScript object from the request into an instance of your DTO, ensuring validation decorators are recognized.
  • whitelist: true: Automatically removes any fields from the request that aren't defined in your DTO, preventing unexpected data from slipping through.
  • The ValidationPipe will throw a BadRequestException with all validation errors if any rules are violated, so you don't need to write manual checks for basic validation.

内容的提问来源于stack exchange,提问作者Dylan Rodriguez

火山引擎 最新活动