ValidationPipe () не работает при переопределении @Query в Nestjs / Crud

#javascript #node.js #typescript #nestjs #class-validator

#javascript #node.js #typescript #nestjs #класс-валидатор

Вопрос:

Я пытаюсь проверить параметры, которые поступают в запросе запроса get, но по какой-то причине канал проверки не может идентифицировать элементы запроса.

 import {
  Controller,
  Post,
  Query,
  Body,
  UseInterceptors,
  Param,
  Res,
  Logger,
} from '@nestjs/common';
import { Crud, CrudController, Override } from '@nestjsx/crud';

import { OpenScheduleDto } from './open-schedule.dto';
@Crud(Schedule)
export class ScheduleController
          implements CrudController<ScheduleService, Schedule> {
          constructor(public service: ScheduleService) {}

          get base(): CrudController<ScheduleService, Schedule> {
            return this;
          }

          @Override()
          async getMany(@Query() query: OpenScheduleDto) { 
             return query; 
         } 
    }
  

OpenSchedule.dto

 import { IsNumber, IsOptional, IsString } from 'class-validator';
export class OpenScheduleDto {

  @IsNumber()
  companyId: number;

  @IsNumber()
  @IsOptional()
  professionalId: number;

  @IsString()
  @IsOptional()
  scheduleDate: string;
}
  

Когда я делаю запрос get на http://localhost:3000/schedules?companyId=3amp;professionalId=1

Я получаю неожиданные ошибки:

 {
    "statusCode": 400,
    "error": "Bad Request",
    "message": [
        {
            "target": {
                "companyId": "3",
                "professionalId": "1"
            },
            "value": "3",
            "property": "companyId",
            "children": [],
            "constraints": {
                "isNumber": "companyId must be a number"
            }
        },
        {
            "target": {
                "companyId": "3",
                "professionalId": "1"
            },
            "value": "1",
            "property": "professionalId",
            "children": [],
            "constraints": {
                "isNumber": "professionalId must be a number"
            }
        }
    ]
}
  

Ответ №1:

Это потому, что при использовании @Query параметров все является строкой. У него нет number или boolean в качестве типов данных, таких как json. Поэтому сначала вам нужно преобразовать ваше значение в число. Для этого вы можете использовать class-transformer ‘s @Transform :

 import { IsNumber, IsOptional, IsString } from 'class-validator';
import { Transform } from 'class-transformer';
export class OpenScheduleDto {

  @Transform(id => parseInt(id))
  @IsNumber()
  companyId: number;

  @Transform(id => id ? parseInt(id) : id)
  @IsNumber()
  @IsOptional()
  professionalId?: number;

  @IsString()
  @IsOptional()
  scheduleDate?: string;
}
  

Обратите внимание, однако, что это небезопасно, потому что, например, parseInt('5abc010') является 5 . Поэтому вы можете захотеть выполнить дополнительные проверки в вашей функции преобразования.

Комментарии:

1. Было бы безопаснее проверить, является ли строка числовой, прежде чем выполнять преобразование? Я предполагаю, что в пакете есть декоратор IsNumberString.

2. @EliseuMonardosSantos Вы можете, например, проверить !isNan(id) и вернуть нетрансформированный идентификатор в противном случае. @IsNumber Средство проверки отклонит нетрансформированную строку.