乐闻世界logo
搜索文章和话题

NestJS 的装饰器 decorator 中进行数据库请求?

8 个月前提问
6 个月前修改
浏览次数47

1个答案

1

在NestJS中,装饰器通常用于声明式地添加元数据、创建参数映射器、定义依赖注入的行为等,并非直接用于执行数据库请求。但是,可以创建自定义装饰器来影响与数据库操作相关的逻辑,比如通过装饰器来获取当前请求的用户,并可能使用这个用户信息来做数据库查询。

举个例子,假设我们需要在多个控制器方法中获取当前已认证的用户,并且可能需要用这个用户的信息来从数据库中获取更多信息。可以创建一个自定义装饰器来完成这个任务:

首先,创建一个装饰器CurrentUser.ts

typescript
import { createParamDecorator, ExecutionContext } from '@nestjs/common'; import { User } from './user.entity'; // 创建一个自定义的参数装饰器 export const CurrentUser = createParamDecorator( async (data: unknown, context: ExecutionContext): Promise<User> => { const request = context.switchToHttp().getRequest(); const user = request.user; // 假设 `request.user` 已经由之前的中间件或者守卫赋值(例如Passport) // 这里可以执行数据库操作,比如使用用户ID查询用户信息 // const userRepository = ...获取你的Repository实例 // const userDetails = await userRepository.findOne(user.id); // 返回用户信息(或者具体的用户详情) // return userDetails; return user; }, );

接着,在控制器中使用此装饰器:

typescript
import { Controller, Get } from '@nestjs/common'; import { CurrentUser } from './decorators/current-user.decorator'; import { User } from './user.entity'; @Controller('profile') export class ProfileController { @Get() async getProfile(@CurrentUser() user: User) { // 在这里,`user` 将会是由 `CurrentUser` 装饰器提供的用户实体 // 可以用这个实体来进行数据库操作,例如获取用户的详细资料等 return user; } }

在上面的例子中,CurrentUser 装饰器用于封装请求对象中的用户信息获取逻辑,并且假设在某个地方(例如Passport的守卫中)已经设置了request.user。在实际使用中,你可以根据需要执行更复杂的数据库查询,并将结果返回给控制器。

需要注意的是,直接在装饰器中执行数据库操作或其他复杂逻辑可能会导致代码难以维护和测试,因此通常建议将这些逻辑放在服务层处理,并在装饰器中仅执行简单的映射或元数据的提取。如果确实需要在装饰器中执行数据库查询,应该确保逻辑清晰,并考虑到性能和错误处理的影响。

2024年6月29日 12:07 回复

你的答案