Search code examples
node.jsgraphqlnestjsclass-validatornestjs-passport

NestJS, GraphQL, class-validator - access request object inside validate method


I have a custom class-validator rule:

import { Injectable } from "@nestjs/common";
import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from "class-validator";

@ValidatorConstraint({ name: "Foo", async: true })
@Injectable()
export class FooRule implements ValidatorConstraintInterface {    
    async validate(value: unknown, args: ValidationArguments) {
        // how to access request object from here?
    }
    
    defaultMessage(args: ValidationArguments) {
        return "NOT OK.";
    }
}

How do I access the request object inside the validate() method?


Solution

  • I ended up using a custom interceptor:

    import { Injectable, NestInterceptor, CallHandler, ExecutionContext } from "@nestjs/common";
    import { GqlExecutionContext } from "@nestjs/graphql";
    import { ForbiddenError } from "apollo-server-core";
    import { Observable } from "rxjs";
    
    @Injectable()
    export class FooInterceptor implements NestInterceptor {
        intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
            // get gql execution context from http one
            const gqlCtx = GqlExecutionContext.create(context);
    
            // holds data passed in a gql input
            const args: unknown[] = gqlCtx.getArgs();
    
            // req object (can be used to obtain jwt payload)
            const req = gqlCtx.getContext().req;
    
            // validation logic here
            const validationPassed = true;
    
            if (validationPassed) {
                // invoke the route handler method 
                return next.handle();
            }
    
            // will be caught by nest exceptions layer
            throw new ForbiddenError("Not allowed.");
        }
    }