Search code examples
javascriptnode.jsdesign-patternsnestjs

How validate query params in nestjs


Yo, i have store application with nestjs, i need validate mongo id, which is pass by query, the problem is that i also pass and search query. I write pipe which validate all values, and exclude this search query

@Injectable()
export class ValidationObjectId implements PipeTransform {
    transform(value: UniqueId, metadata: ArgumentMetadata) {
        if (
            !Types.ObjectId.isValid(value) &&
            metadata.data !== "searchString"
        ) {
            throw new BadRequestException("Неверный параметр запроса");
        }

        return value;
    }
}

But this code not reusable for other case. I want get some examples, how i can do this


Solution

  • The cleanest and most reusable approach would probably be to make use of the ValidationPipe with a Query-DTO-Class.

    Take a look at the following example.

    https://gitlab.com/WaldemarLehner/nestjs-swagger-example/-/tree/1aea48597ddcf93b0a0d1449fe5087413415bbee

    Inside the Controller you can pass a Pipe to the @Query()-Decorator. You can use the ValidationPipe which already comes with Nest and makes use of the class-validator and class-transformer Packages.

    You can create a DTO-Class for your Query-Parameters as done in the PostHelloQuery.dto.ts from my example.

    import { IsBoolean, IsOptional } from "class-validator";
    
    export class PostHelloQueryDTO {
        @IsOptional()
        @IsBoolean()
        public useExclamation?: boolean;
    }
    

    Here you define constraints for your Data using decorators from class-validator. For a list of all decorators, please refer to https://github.com/typestack/class-validator#validation-decorators .

    If none of the validators fit your needs you can also create your own Decorator as shown here.

    In my example, the useExclamation-Query Param is an optional boolean. Note that incoming query parameters are parsed as strings.

    The conversion is done using the enableInplicitConversion-Option as seen in the Controller:

    @Query(new ValidationPipe({
        transform: true,
        transformOptions: {enableImplicitConversion: true},
        forbidNonWhitelisted: true
    })) query: PostHelloQueryDTO
    

    For more information about using ValidationPipe with class-validator, you can take a look at the NestJS Documentation:

    https://docs.nestjs.com/techniques/validation

    For your specific Use-Case (Validating MongoDB IDs), I have found an open Issue with an Example Implementation for a @IsMongoDB-Decorator:

    https://github.com/typestack/class-validator/issues/630#issuecomment-645638436