You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJs中如何为不同端点隐藏同一DTO的特定Swagger属性

解决方案:NestJS 同一 DTO 为不同端点展示不同属性

针对你遇到的问题,目前没有直接在@Body()装饰器层面排除属性的Swagger装饰器,但可以通过以下几种方案实现需求:

方案1:使用@ApiBody()自定义请求体Schema

在控制器的每个端点上,通过@ApiBody()装饰器指定该端点需要展示的属性,直接覆盖DTO的默认Swagger配置:

import { ApiBody } from '@nestjs/swagger';

@Controller('users')
export class UsersController {
  // 端点1:使用4个属性
  @Patch('/profile')
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        username: { type: 'string' },
        email: { type: 'string' },
        avatar: { type: 'string' },
        bio: { type: 'string' }
      },
      required: ['username'] // 可选:指定必填属性
    }
  })
  updateUserProfile(@Body() updateUserDto: UpdateUserDTO) {
    // 逻辑处理
  }

  // 端点2:使用2个属性
  @Patch('/password')
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        oldPassword: { type: 'string' },
        newPassword: { type: 'string' }
      },
      required: ['oldPassword', 'newPassword']
    }
  })
  updateUserPassword(@Body() updateUserDto: UpdateUserDTO) {
    // 逻辑处理
  }
}

这种方式不需要修改原DTO,直接在控制器层面定制每个端点的Swagger展示内容。

方案2:基于基础DTO创建子类,通过@ApiHideProperty()控制展示

创建继承自UpdateUserDTO的子类,在子类中给不需要展示的属性添加@ApiHideProperty():

// 基础DTO
export class UpdateUserDTO {
  @ApiProperty()
  username: string;

  @ApiProperty()
  email: string;

  @ApiProperty()
  avatar: string;

  @ApiProperty()
  bio: string;

  @ApiProperty()
  oldPassword: string;

  @ApiProperty()
  newPassword: string;
}

// 用于端点1的子类
export class UpdateUserProfileDTO extends UpdateUserDTO {
  @ApiHideProperty()
  oldPassword: never;

  @ApiHideProperty()
  newPassword: never;
}

// 用于端点2的子类
export class UpdateUserPasswordDTO extends UpdateUserDTO {
  @ApiHideProperty()
  username: never;

  @ApiHideProperty()
  email: never;

  @ApiHideProperty()
  avatar: never;

  @ApiHideProperty()
  bio: never;
}

然后在控制器中使用对应的子类:

@Patch('/profile')
updateUserProfile(@Body() updateUserDto: UpdateUserProfileDTO) {
  // 逻辑处理
}

@Patch('/password')
updateUserPassword(@Body() updateUserDto: UpdateUserPasswordDTO) {
  // 逻辑处理
}

方案3:使用NestJS mapped-types的PickType快速生成DTO

NestJS提供的mapped-types工具可以快速从基础DTO中挑选指定属性生成新的DTO,这是官方推荐的简洁方案:

import { PickType } from '@nestjs/mapped-types';
import { ApiProperty } from '@nestjs/swagger';

// 基础DTO
export class UpdateUserDTO {
  @ApiProperty()
  username: string;

  @ApiProperty()
  email: string;

  @ApiProperty()
  avatar: string;

  @ApiProperty()
  bio: string;

  @ApiProperty()
  oldPassword: string;

  @ApiProperty()
  newPassword: string;
}

// 挑选端点1需要的4个属性
export class UpdateUserProfileDTO extends PickType(UpdateUserDTO, [
  'username',
  'email',
  'avatar',
  'bio'
] as const) {}

// 挑选端点2需要的2个属性
export class UpdateUserPasswordDTO extends PickType(UpdateUserDTO, [
  'oldPassword',
  'newPassword'
] as const) {}

控制器中直接使用这些生成的DTO即可,Swagger会自动展示对应的属性,同时类型检查也能正常工作。


内容的提问来源于stack exchange,提问作者M Nouman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 14:18:12