Búsqueda de sitios web

typescript - NestJs obtener la instancia de la solicitud o el contexto de ejecución en un validador personalizado (class validator)


¿Es posible inyectar el contexto de ejecución o acceder a la solicitud actual en NestJs (class-validator => validador personalizado)?

import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';
import { Injectable } from '@nestjs/common';
import { Connection } from 'typeorm';
import { InjectConnection } from '@nestjs/typeorm';

@ValidatorConstraint({ name: 'modelExistsConstraint', async: true })
@Injectable()
export class ModelExistsConstraint implements ValidatorConstraintInterface {

  constructor(
    @InjectConnection('default') private readonly connection: Connection,
  ) {
  }

  async validate(value: string, validationArguments: ValidationArguments) {
    // here need request or execution context;
    // const test = this.context.switchToHttp().getRequest();
    const model = await this.connection
      .getRepository(validationArguments.constraints[0])
      .findOne({ where: { [validationArguments.property]: value } });
    return !model;
  }

  defaultMessage(args: ValidationArguments) {
    return `Model with "${args.property}" - "${args.value}" already exists`;
  }
}

Respuesta #1

Creo que deberías usar algo como ClsModule de la librería nestjs-cls, esto te permitirá obtener variables de la solicitud. Porque si estás usando el DTO con el ValidationPipe, no tendrá acceso al contexto de ejecución.

Además, esto te permitirá tener servicios singleton en lugar de los de alcance REQUEST.

Respuesta #2

Sugeriría separar la validación del cuerpo de la solicitud y la lógica de negocio. Su validador deseado parece coincidir con la lógica de negocio en lugar de con la validación y creo que es mucho más fácil validar que un modelo ya exista directamente en nuestra lógica de negocio, como se muestra en el siguiente ejemplo:

@Injectable()
class ExampleService {
 async someBusinessLogic() {
  if(await this.connection
      .getRepository(validationArguments.constraints[0])
      .findOne({ where: { ... } })) {
    throw new BadRequestException("Model already exists")
   }
    // more logic..
 }
}

Artículos relacionados