Reputation: 608
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);
}
}
Upvotes: 3
Views: 4822
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
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
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