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

如何在NestJS中将Prisma数据模型映射为不含Token字段的DTO?

解决NestJS返回用户数据时移除Token等多余字段的方案

你遇到的问题是plainToClass默认不会自动剔除原始对象的多余属性,再加上可能未正确处理异步查询结果,导致返回数据包含Token等不必要字段。以下是几种可行的解决方法:


方法一:配置class-transformer并通过装饰器明确字段

通过class-transformer的装饰器标记需要保留的字段,同时开启移除多余属性的配置:

  1. 确保安装class-transformer:
npm install class-transformer
  1. 修改UserDto,用装饰器明确保留字段:
import { Exclude, Expose } from 'class-transformer';

@Exclude() // 默认排除所有未标记@Expose的字段
export class UserDto {
    @Expose()
    id: string;

    @Expose()
    firstName: string;

    @Expose()
    lastName: string;

    @Expose()
    email: string;

    @Expose()
    nationalityCode: string;

    @Expose()
    countryCode: string;

    @Expose()
    contactNumber: string;

    @Expose()
    passportNumber?: string;

    @Expose()
    nicNumber?: string;

    @Expose()
    dateOfBirth?: Date;

    @Expose()
    profilePictureKey?: string;

    @Expose()
    preferredLocaleId: string;
}
  1. 修正服务层代码,await异步查询结果并添加配置:
import { plainToClass } from 'class-transformer';

async getUserById(id: string) {
  // Prisma查询是异步的,必须await获取结果
  const user = await this.userRepository.getUser(id);
  // 开启excludeExtraneousValues移除多余属性
  return plainToClass(UserDto, user, { excludeExtraneousValues: true });
}

方法二:直接在Prisma查询时指定返回字段(性能最优)

从数据库查询阶段就只获取需要的字段,避免后续转换操作:

修改userRepository.getUser方法,使用Prisma的select选项:

// userRepository.ts
async getUser(id: string) {
  return this.prisma.user.findUnique({
    where: { id },
    select: {
      id: true,
      firstName: true,
      lastName: true,
      email: true,
      nationalityCode: true,
      countryCode: true,
      contactNumber: true,
      passportNumber: true,
      nicNumber: true,
      dateOfBirth: true,
      profilePictureKey: true,
      preferredLocaleId: true,
    },
  });
}

这种方式返回的对象本身就没有Token等多余字段,无需再用plainToClass转换。


方法三:使用NestJS的ClassSerializerInterceptor(优雅方案)

结合NestJS拦截器自动处理DTO转换,无需手动调用plainToClass:

  1. 在控制器上添加拦截器:
import { Controller, Get, Param, UseInterceptors } from '@nestjs/common';
import { ClassSerializerInterceptor } from '@nestjs/common';
import { UserDto } from './dto/user.dto';

@Controller('users')
@UseInterceptors(ClassSerializerInterceptor) // 可全局或控制器级别配置
export class UsersController {
  constructor(private readonly userService: UsersService) {}

  @Get(':id')
  async getUser(@Param('id') id: string): Promise<UserDto> {
    // 直接返回用户对象,拦截器会自动转换为UserDto格式
    return this.userService.getUser(id);
  }
}
  1. 同样需要给UserDto添加@Exclude()和@Expose()装饰器(同方法一的Dto代码)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:48:11