Reputation: 1797
I am a beginner in Nest.js and I found it extremely good. I read the official docs and learned about DTOs. When My Body is like this:
{
"username" : "username",
"password" : "password"
}
then I can simply create user.dto.ts
like this:
import { IsNotEmpty } from 'class-validator';
export class UserDTO {
@IsNotEmpty()
username: string;
@IsNotEmpty()
password: string;
}
Then I use this in my controller like this.
@Post('login')
@UsePipes(new ValidationPipe())
login(@Body() data: UserDTO) {
return this.userService.login(data);
}
But my question is what if my Body is something like this.
{
"data": {
"username": "username",
"password": "password",
}
}
then what modifications I need to make in my ```user.dto.ts`` file to make it work? Thanks
Upvotes: 13
Views: 26203
Reputation: 591
You may create a wrapper class that would carry your dto such as
export class Data<T> {
@ApiModelProperty()
readonly data: T;
constructor(data: any = {}) {
this.data = data;
}
}
and in your controller you will have
@Post('login')
@UsePipes(new ValidationPipe())
login(@Body() data: Data<UserDTO>) {
return this.userService.login(data);
}
in your service you will do something like
return new Data(this.userDto);
Upvotes: 2
Reputation: 5098
The answer is: You don't need to modify your DTO
.
@Body()
decorator also takes in an optional argument: @Body(path?: string)
.
The key here is to understand what @Body()
does. @Body()
without any argument will return req.body
object. @Body('path')
will return req.body.path
(or req.body['path']
. With this knowledge, you can pass 'data'
in @Body('data')
and it will return req.body.data
which will be your DTO
.
@Post('login')
@UsePipes(new ValidationPipe())
login(@Body('data') data: UserDTO) {
// data will be your req.body.data which is your UserDTO
return this.userService.login(data);
}
Upvotes: 38