从Nestjs控制器访问元数据

发布于 2025-02-13 04:53:54 字数 408 浏览 1 评论 0 原文

有没有办法从控制器方法访问元数据?

例如,我将元数据添加到带有装饰器的setMetadata()的控制器类中。

我知道如何在警卫中访问元数据。您需要注入反射器和guard.canactivate()具有exputionContext参数。

canActivate(context: ExecutionContext): boolean {
  metadata: SomeType = this.reflector.get<EnabledFeatures>(SOME_METADATA_KEY, [context.getClass()]);
}

要获得元数据,我需要2个组件:反射器和执行context。 我可以将Reflector注入控制器,但是如何从控制器访问ExecutionContext?

is there a way to access metadata from controller methods?

For example, I add metadata to a controller class with SetMetadata() - e.g. from a decorator.

I know how to access metadata in a guard. You need to inject reflector and guard.canActivate() has ExecutionContext parameter.

canActivate(context: ExecutionContext): boolean {
  metadata: SomeType = this.reflector.get<EnabledFeatures>(SOME_METADATA_KEY, [context.getClass()]);
}

To get metadata I need 2 components: Reflector and ExecutionContext.
I can inject Reflector into controller, but how can I access ExecutionContext from a controller?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

明媚殇 2025-02-20 04:53:54

假设我们使用 @setMetadata Controller 上设置了一些元数据:

@Controller({...})
@SetMetadata('roles', ['admin'])

我们可以通过创建我们的自定义参数装饰器

export const Roles = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    // get roles metadata from @Controller class
    const roles = Reflect.getMetadata('roles', ctx.getClass());
    return roles;
  },
);

然后我们可以在控制器的方法上使用它:

@Get()
getInfo(@Roles() roles): string {
  // roles = ['admin']

  //...
}

一些注释

@setMetadata不是直接的 @setMetadata 的好习惯

用法并不是真正的好习惯。更喜欢创建特定的装饰器(用于代码的维护和可读性):

export const SetRoles = (...roles: string[]) => SetMetadata('roles', roles);

...

@Controller({...})
@SetRoles('admin')
export class MyController {...}
fover.getMetadata api vs喷油器

,即使 Reffled.getMetAdata is 反射器 Nestjs的API,将来可能会更改。
因此,如果我们只想处理Nestjs的公共/记录的API,我们可以:

  • 使用a Global Guard ,它将注入注入器
  • 使用 executionContext 获取元数据
  • ,然后在 request request 实例中设置结果。

其他自定义参数装饰器将从请求中检索数据并将其返回。

更复杂,但不使用直接调用 Reflect.getMetadata api。

Assuming we set some metadata on Controller with @SetMetadata :

@Controller({...})
@SetMetadata('roles', ['admin'])

We can have access to it, by creating our custom param decorator:

export const Roles = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    // get roles metadata from @Controller class
    const roles = Reflect.getMetadata('roles', ctx.getClass());
    return roles;
  },
);

And then we can use it on controller's method :

@Get()
getInfo(@Roles() roles): string {
  // roles = ['admin']

  //...
}

Some notes

@SetMetadata not a good practice

Usage of @SetMetadata directly is not really a good practice. Prefer to create a specific decorator (for maintenance and readability of code) :

export const SetRoles = (...roles: string[]) => SetMetadata('roles', roles);

...

@Controller({...})
@SetRoles('admin')
export class MyController {...}
Reflect.getMetadata API vs Injector

Even if Reflect.getMetadata is in fact called by Reflector API of NestJS, it could be changed in the future.
So if we want to deal with only public/documented API of NestJS, we can:

  • use a global guard, which will inject Injector,
  • get metadata with ExecutionContext
  • and then set result in Request instance.

An other custom param decorator will retrieve data from Request and return it.

More complicated, but without using direct call to Reflect.getMetadata API.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文