如何清理 Node.js 和 Typescript 中的响应正文

Posted

技术标签:

【中文标题】如何清理 Node.js 和 Typescript 中的响应正文【英文标题】:How to sanitize response body in Node.js and Typescript 【发布时间】:2021-03-19 21:54:09 【问题描述】:

我有一个在 node.js 上使用 nest.js 作为框架的 typescript 编写的后端服务器。

我想自动清理我的控制器的响应主体,删除我的 DTO 的未声明属性。

我有以下文件:

class User 
   _id: string
   name: string
   hashedPassword: string

class UserDTO 
   _id: string
   name: string

@ApiTags('users')
@Controller('users')
export class UsersController 
...
    @Get(':id')
    @UseGuards(JwtAuthGuard)
    @ApiBearerAuth()
    @ApiOperation( summary: 'Find one user by id' )
    @ApiResponse(
        status: 200,
        type: UserDto,
    )
    async findOne(@Param('id') id: string): Promise<UserDto> 
        return await this.usersService.findById(id) as UserDto;
    

当我声明 user as UserDTO 时,我认为这将删除所有未声明的属性作为 UserDTO(在本例中为“hashedPassword”),但事实并非如此,它仍然发送“hashedPassword”,我想在不调用构造函数的情况下自动删除它或在每个服务上使用const hashedPassword, ...result = user; return result; 手动删除它。

每次我必须发送 DTO 时,都很难进行这种转换。我正在寻找能够自动进行这种转换的东西。 typescript 或 Nest.js 中是否存在自动为我执行此转换的内容?可能是 DTO 中的一些装饰器或调用一些中间件?

在旧项目中,我曾经这样做是为了自动删除不需要的属性:

const UserSchema = new Schema(
    hashedPassword: String,
    ...
, 
    timestamps: true,
    toJSON: 
        transform: (doc, ret, options) => 
            delete ret.hashedPassword;
            return ret;
        ,
        virtuals: false,
    
);

今天我认为这是一个糟糕的实现,因为我将业务逻辑添加到我的存储库中。我正在寻找能够自动清理我的 DTO 的东西。这可能吗?

【问题讨论】:

user as UserDTO 在运行时做任何事情。它不能;所有类型信息都在编译时被删除,因为 javascript 没有类型。 【参考方案1】:

听起来你可能在寻找Serialization,Nest 有一个带有拦截器的设置,class-transformer 调用classToPlain() 来序列化响应。听起来您可能正在使用 Mongo,因此请记住,您可能需要在服务中做一些额外的工作才能获得 class-transformer 可以使用的真实类实例。

至于为什么您的上述尝试不起作用,正如 jonrsharpe 在 cmets 中提到的那样,类型信息在运行时不存在。它纯粹是在开发和编译期间为开发人员提供的,以帮助我们捕获可以轻松避免的错误。此外,更进一步,x as y 告诉编译器“我知道x 的类型为y,无论您是否可以从我编写的代码中读取它”。它本质上是告诉编译器你知道的比它多,所以它不应该担心。

【讨论】:

以上是关于如何清理 Node.js 和 Typescript 中的响应正文的主要内容,如果未能解决你的问题,请参考以下文章

如何删除多行 typeorm - postgresql 和 node.js(typescript)

如何让 TypeScript 以生成工作 Node.JS 代码的方式加载 PDF.js NPM 模块和 @types 绑定?

Typescript:如何解析 node.js 的绝对模块路径?

在 Node.js 和 Vue.js 之间共享 TypeScript 代码

使用 Visual Studio 2012 express 进行 TypeScript、node.js 开发

如何使用 TypeScript 导入自定义 node.js 插件模块