如何在 Nest.js 中为 @Body 构造 DTO

How to construct DTO in Nest.js for @Body

我是 Nest.js 的初学者,我发现它非常好。我阅读了官方文档并了解了 DTO。当我的Body是这样的时候:

{
  "username" : "username",
  "password" : "password"
}

然后我可以像这样简单地创建 user.dto.ts

import { IsNotEmpty } from 'class-validator';

export class UserDTO {
  @IsNotEmpty()
  username: string;
  @IsNotEmpty()
  password: string;
}

然后我像这样在我的控制器中使用它。

  @Post('login')
  @UsePipes(new ValidationPipe())
  login(@Body() data: UserDTO) {
    return this.userService.login(data);
  }

但我的问题是如果我的 Body 是这样的怎么办。

{
  "data": {
    "username": "username",
    "password": "password",
  }
}

那么我需要对我的 ```user.dto.ts`` 文件进行哪些修改才能使其正常工作?谢谢

答案是:您不需要修改您的DTO

@Body() 装饰器还接受一个可选参数:@Body(path?: string).

这里的关键是理解 @Body() 的作用。 @Body() 不带任何参数将 return req.body 对象。 @Body('path') 将 return req.body.path(或 req.body['path']。有了这些知识,您可以在 @Body('data') 中传递 'data',它将 return req.body.data 这将是你的 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);
}

您可以创建一个包装器 class 来携带您的 dto,例如

export class Data<T> {

  @ApiModelProperty()
  readonly data: T;

  constructor(data: any = {}) {
    this.data = data;
  }
}

并且在您的控制器中您将拥有

@Post('login')
@UsePipes(new ValidationPipe())
login(@Body() data: Data<UserDTO>) {
 return this.userService.login(data);
}

在你的服务中你会做类似

的事情
return new Data(this.userDto);