How to construct DTO in Nest.js for @Body

19,143

Solution 1

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);
}

Solution 2

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);
Share:
19,143
Usama Tahir
Author by

Usama Tahir

Software Engineer currently working as a Full STACK developer at GoSaas.

Updated on June 05, 2022

Comments

  • Usama Tahir
    Usama Tahir almost 2 years

    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