有没有办法从 NestJS 应用程序中收集所有方法及其路径?

yum*_*maa 2 typescript nestjs

我需要编写中间件来处理请求,但应该排除一些路径。我不想手动硬编码所有这些,所以我有一个想法:

创建特殊的装饰器,它将标记要排除的方法,如下所示:

import { ReflectMetadata } from '@nestjs/common';
export const Exclude = () =>
  ReflectMetadata('exclude', 'true');
Run Code Online (Sandbox Code Playgroud)

在创建 NestJS 应用程序后,有没有办法以某种方式递归获取所有方法,用这个装饰器注释,自动添加它们的路径以排除在我的中间件中?

Jes*_*ter 7

我发布了一个可重用的模块,用于发现处理程序或 Injectable 类的元数据,专门支持这种模式。您可以@nestjs-plus/common从 NPM中获取,然后DiscoveryService根据您提供的 MetaData 令牌使用自动检索所有匹配的处理程序或类。源代码可在 Github 上获得。我将在短期内继续更新文档,但存储库中已经包含了它的几个示例用法。

在幕后,它使用 MetaDataScanner,但将事情包装在一个很好的易于使用的 API 中。查看您发布的代码片段,这可能有助于为您的特定用例减少大量样板文件。您可以在@nestjs-plus/rabbitmq模块(来自同一个存储库)中看到更多高级用法,了解如何使用它来将高级功能粘合在一起

编辑:我已经更新了库以支持发现控制器和控制器方法的场景以支持您的场景。有一个完整的测试套件,可以使用@Roles装饰器模拟您的设置,您可以查看。. 在DiscoveryModule导入中包含并注入 之后,DiscoverService您可以使用简化的methodsAndControllerMethodsWithMetaAPI找到所有控制器方法。

// Inject the service
constructor(private readonly discover: DiscoveryService) { }

// Discover all controller methods decorated with guest roles or 
// belonging to controllers with guest roles

const allMethods = this.discover.methodsAndControllerMethodsWithMeta<string[]>(
  rolesMetaKey,
  x => x.includes('guest')
);
Run Code Online (Sandbox Code Playgroud)

在你发现了你想要的所有方法之后,你可以对它们做任何你想做的事情,在你的情况下,建立一个它们的RequestMethodpath.

const fullPaths = allGuestMethods.map(x => {
  const controllerPath = Reflect.getMetadata(
    PATH_METADATA,
    x.component.metatype
  );

  const methodPath = Reflect.getMetadata(PATH_METADATA, x.handler);
  const methodHttpVerb = Reflect.getMetadata(
    METHOD_METADATA,
    x.handler
  );

  return {
    verb: methodHttpVerb,
    path: `${controllerPath}/${methodPath}`
  }
});
Run Code Online (Sandbox Code Playgroud)

这会给你这样的东西(取自链接的测试套件)。

expect(fullPaths).toContainEqual({verb: RequestMethod.GET, path: 'guest/route-path-one'});
expect(fullPaths).toContainEqual({verb: RequestMethod.GET, path: 'super/route-path-two'});
expect(fullPaths).toContainEqual({verb: RequestMethod.POST, path: 'admin/route-path-three'});
Run Code Online (Sandbox Code Playgroud)

随时提供有关方法/API 的反馈。