如何清理 Node.js 和 Typescript 中的响应主体
How to sanitize response body in Node.js and Typescript
我在 node.js 上使用 nest.js 作为框架用打字稿编写了一个后端服务器。
我想自动清理我的控制器的响应主体,删除我的 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 时进行这种转换很痛苦。我正在寻找可以自动进行这种转换的东西。打字稿或 Nest.js 中是否存在自动为我进行此转换的内容?也许是 DTO 中的一些装饰器或调用了一些中间件?
在较旧的项目中,我曾经这样做以自动删除不需要的属性:
const UserSchema = new Schema({
hashedPassword: String,
...
}, {
timestamps: true,
toJSON: {
transform: (doc, ret, options) => {
delete ret.hashedPassword;
return ret;
},
virtuals: false,
}
});
今天我认为这是一个糟糕的实现,因为我将业务逻辑添加到我的存储库中。我正在寻找可以自动清理我的 DTO 的东西。这可能吗?
听起来你 可能 正在寻找 Serialization,Nest 有一个带有拦截器的设置并且 class-transformer
调用 classToPlain()
来序列化响应。听起来您可能正在使用 Mongo,因此请记住,您可能需要在服务中做一些额外的工作才能获得 class-transformer
可以使用的真实 class 实例。
至于为什么你上面的尝试没有成功,正如jonrsharpe在评论中提到的,类型信息在运行时不存在。它纯粹是为开发人员在开发和编译期间提供的,以帮助我们捕获可以轻松避免的错误。此外,更进一步,x as y
告诉编译器“我知道 x
是 y
类型,无论您是否可以从我编写的代码中读取它”。它本质上是在告诉编译器你知道的比它多,所以它不应该担心。
我在 node.js 上使用 nest.js 作为框架用打字稿编写了一个后端服务器。
我想自动清理我的控制器的响应主体,删除我的 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 时进行这种转换很痛苦。我正在寻找可以自动进行这种转换的东西。打字稿或 Nest.js 中是否存在自动为我进行此转换的内容?也许是 DTO 中的一些装饰器或调用了一些中间件?
在较旧的项目中,我曾经这样做以自动删除不需要的属性:
const UserSchema = new Schema({
hashedPassword: String,
...
}, {
timestamps: true,
toJSON: {
transform: (doc, ret, options) => {
delete ret.hashedPassword;
return ret;
},
virtuals: false,
}
});
今天我认为这是一个糟糕的实现,因为我将业务逻辑添加到我的存储库中。我正在寻找可以自动清理我的 DTO 的东西。这可能吗?
听起来你 可能 正在寻找 Serialization,Nest 有一个带有拦截器的设置并且 class-transformer
调用 classToPlain()
来序列化响应。听起来您可能正在使用 Mongo,因此请记住,您可能需要在服务中做一些额外的工作才能获得 class-transformer
可以使用的真实 class 实例。
至于为什么你上面的尝试没有成功,正如jonrsharpe在评论中提到的,类型信息在运行时不存在。它纯粹是为开发人员在开发和编译期间提供的,以帮助我们捕获可以轻松避免的错误。此外,更进一步,x as y
告诉编译器“我知道 x
是 y
类型,无论您是否可以从我编写的代码中读取它”。它本质上是在告诉编译器你知道的比它多,所以它不应该担心。