NestJs get request instance or execution context in custom validator (class validator)
Asked Answered
O

2

16

Is it possible to inject execution context or access current request in nestJs (class-validator => custom validator) ?

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`;
  }
}
Octahedrite answered 13/9, 2018 at 16:4 Comment(3)
did you find a solution ?Quiroz
How are you instantiating or applying your custom validator? ValidationPipe?Dieselelectric
I found the answer here - github.com/nestjs/nest/issues/173. I used a library called cls hooks - npmjs.com/package/cls-hookedOctahedrite
P
0

I think you should use something like ClsModule from the nestjs-cls library this will allow you to get variables from the request. Because if you are using the DTO with the ValidationPipe it will not have access to the execution context.

Also, this will allow you to have singleton services instead of REQUEST scoped ones.

Persuasion answered 11/5, 2023 at 14:31 Comment(0)
L
0

I would suggest to separate request body validation and business logic. Your desired validator seems to match business logic instead of validation and i think it is much easier to validate that a model already exists directly in our business logic like shown in following example:

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

Leto answered 4/1 at 20:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.