Reputation: 53
I'm messing around with NestJS and class-validators for the first time. In that context I met something I didn't quite understand, and haven't been able to find an explanation online.
I'm struggling to understand how exactly the library understands my DTO and what is valid and what is not due to the fact the DTO is ONLY being used as a type. How exactly does this work?
Here is is an example DTO:
export class LoginDto {
@IsEmail()
email: string;
@IsString()
password: string;
}
Here is an example in NestJS where I validate the body based on the DTO:
@Post('login')
login(@Body() body: LoginDto) {
return this.authService.login(body);
}
So just to reiterate my question one more time. How is the body being validated against the DTO when it's only declared as a TYPE, which surely doesn't have anything to do with runtime, right? Right?
Thanks in advance :)
Upvotes: 1
Views: 1470
Reputation: 70191
So NestJS by default makes use of Typescript metadata emitted from decorators and the libraries class-transformer
(abv. c-t) and class-validator
(abv. c-v) for the body validation via the ValidaitonPipe
. On compilation, Typescript will emit some metadata about the code, what parameters are in a method, if they have a class type, what metadata should be attached to them (designtype:params
, req.body
, etc), and other useful data that Nest or c-t
/c-v
reads at runtime. Nest uses some of this metadata to pass on proper values to the pipe, like what class type is set for a decorator (like your LoginDto
) and what part of the request the value comes from (this is determined by @Body()
/@Query()
/@Param()
/etc) and these are passed to the pipe in the second parameter of the transform()
method under ArgumentMetadata
. Then, the class type is passed on to c-t
so that plainToInstance(ClassType, value)
can be called to make a class instance of the LoginDto
and then c-v
's validate
is called to validate that each parameter of the instance properly matches the @IsWhatever()
decorators that are assigned to the property. Really interesting stuff.
I highly suggest you take a look at the emitted compiled JavaScript after running your build
command to get a better idea of what is being emitted and thus read at runtime
Upvotes: 1