SebMaz
SebMaz

Reputation: 608

How to use Prisma with ValidationPipe in NestJS?

I'm trying to use Prisma with ValidationPipe that NestJS provides but it is not working, I was using class-validator package with DTO's (classes) as ValidationPipes and it was working fine, now I need a way to use the same pattern with Prisma without the need of DTOs to not have duplicated types. (I want to avoid creating custom pipes for validation)

DTO FILE:

import { IsNotEmpty } from 'class-validator';

export class TodoCreateDto {
  @IsNotEmpty()
  title: string;

  @IsNotEmpty()
  description: string;
}

WITH DTO: working

@Controller('todos')
export class TodosController {
  constructor(private todosService: TodosService) {}

  @Post()
  @UsePipes(ValidationPipe)
  createTodo(@Body() todoCreateDto: TodoCreateDto) {
    return this.todosService.createTodo(todoCreateDto);
  }
}

WITH PRISMA: not working

@Controller('todos')
export class TodosController {
  constructor(private todosService: TodosService) {}

  @Post()
  @UsePipes(ValidationPipe)
  createTodo(@Body() todoCreateInput: Prisma.TodoCreateInput) {
    return this.todosService.createTodo(todoCreateInput);
  }
}

full code repo link

Upvotes: 3

Views: 4822

Answers (3)

KAVYA SHARMA
KAVYA SHARMA

Reputation: 104

Prisma.TodoCreateInput is not a class but just typescript interface. For nestjs validation pipe to work it requires a javascript class with each property decorated with decorators from class-validator.

There is no way for nestjs validation pipe to validate the request.body using a typescript type or interface.

Extra :- Although if you want to avoid writing your dto's, Prisma itself validates it's input and if fails it raises PrismaClientValidationError you can catch this globally using Nestjs exception filters and give client a 400 or any other error with prisma exceptoin message.

Upvotes: 2

Daniel Salahi
Daniel Salahi

Reputation: 121

you have three solutions for it: Continue Using DTOs, Custom Validation Pipe, hybrid:

The decision largely depends on your project's specific needs and your team's familiarity with these patterns. If maintaining a clear separation and leveraging existing NestJS features is important, continue using DTOs. If reducing redundancy is a priority, consider the dynamic DTO generation or custom validation pipe approach.

   import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class TransformInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler<any>) {
    const request = context.switchToHttp().getRequest();
    request.body = new TodoCreateDto(request.body.title, request.body.description);
    return next.handle().pipe(map(data => data));
  }
}

Upvotes: 3

Jay McDoniel
Jay McDoniel

Reputation: 70191

Nest's ValidationPipe works by default by using class-validator and class-transformer, and classes for the DTO. Without the class having these libraries' decorators, the pipe won't do anything for you. You'd need some way to tell Prisma to generate class types that relate to the SDL with the class-validator decorators, which at this moment I don' think is possible.

Upvotes: 1

Related Questions