проверка массива идентификаторов uuid в теле nestjs swagger

#nestjs #class-validator #nestjs-swagger

#nestjs #средство проверки класса #nestjs-swagger

Вопрос:

Это звучит как довольно простой вопрос, но я искал решение уже очень долгое время. Я хочу проверить массив идентификаторов UUID в конечной точке.

Вот так: ["9322c384-fd8e-4a13-80cd-1cbd1ef95ba8", "986dcaf4-c1ea-4218-b6b4-e4fd95a3c28e"]

Я уже успешно реализовал его как объект JSON { "id": ["9322c384-fd8e-4a13-80cd-1cbd1ef95ba8", "986dcaf4-c1ea-4218-b6b4-e4fd95a3c28e"]} со следующим кодом:

 public getIds(
  @Body(ValidationPipe)
  uuids: uuidDto
) {
  console.log(uuids);
}
 
 import { ApiProperty } from '@nestjs/swagger';
import { IsUUID } from 'class-validator';

export class uuidDto {
  @IsUUID('4', { each: true })
  @ApiProperty({
    type: [String],
    example: [
      '9322c384-fd8e-4a13-80cd-1cbd1ef95ba8',
      '986dcaf4-c1ea-4218-b6b4-e4fd95a3c28e',
    ],
  })
  id!: string;
}
 

Но, к сожалению, я не могу настроить функцию, которая вызывает эту конечную точку. Итак, мне нужно решение для проверки только массива uuid.

Ответ №1:

вместо типа string напишите string[] . как показано ниже:

 import { ApiProperty } from '@nestjs/swagger';
import { IsUUID } from 'class-validator';

export class uuidDto {
  @IsUUID('4', { each: true })
  @ApiProperty({
    type: string[],
    example: [
      '9322c384-fd8e-4a13-80cd-1cbd1ef95ba8',
      '986dcaf4-c1ea-4218-b6b4-e4fd95a3c28e',
    ],
  })
  id!: string[];
}
 

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

1. Но тогда проблема по-прежнему в том, что у меня есть объект с идентификатором свойства, который является массивом, я хочу иметь только массив без необходимости свойства id

2. Итак, я предполагаю, что подход DTO неверен, поскольку у меня нет объекта

3. да, вам не нужен объект, но если вы думаете, что вам это нужно, просто создайте для него интерфейс и экспортируйте его, а затем используйте в своем dto

Ответ №2:

Вы можете создать для него пользовательский канал проверки:

 @Injectable()
export class CustomClassValidatorArrayPipe implements PipeTransform {

  constructor(private classValidatorFunction: (any)) {}

  transform(value: any[], metadata: ArgumentMetadata) {
    const errors = value.reduce((result, value, index) => {
      if (!this.classValidatorFunction(value))
        result.push(`${value} at index ${index} failed validation`)
      return result
    }, [])

    if (errors.length > 0) {
      throw new BadRequestException({
        status: HttpStatus.BAD_REQUEST,
        message: 'Validation failed',
        errors
      });
    }

    return value;
  }
}
 

В вашем контроллере:

 @Post()
createExample(@Body(new CustomClassValidatorArrayPipe(isUUID)) body: string[]) {
  ...
}
 
  • Убедитесь, что вы используете функции нижнего регистра из class-validator. Это должно быть isUUID вместо IsUUID . (Это используется для ручной проверки с помощью class-validator.)
  • CustomClassValidatorArrayPipe сборка модульная. Вы можете проверить любой другой тип с его помощью. Например, MongoId : @Body(new CustomClassValidatorArrayPipe(isMongoId)) body: ObjectId[]

Результат

Если вы отправите это:

 POST http://localhost:3000/example
Content-Type: application/json

[
  "986dcaf4-c1ea-4218-b6b4-e4fd95a3c28e",
  "123",
  "test"
]
 

Сервер ответит:

 {
  "status": 400,
  "message": "Validation failed",
  "errors": [
    "123 at index 1 failed validation",
    "test at index 2 failed validation"
  ]
}