NestJS 控制器中的重载路由?

yum*_*maa 5 typescript nestjs

在 NestJS 应用程序中是否有一种漂亮的方式来创建重载路由?我有一些想法,但也许我正在发明一个轮子。虽然我找不到任何现成的方法......

我正在谈论的是这样的事情(让我们以https://github.com/nestjs/nest/blob/master/sample/01-cats-app/src/cats/cats.controller.ts作为起点) :

@Get()
async findAll(): Promise<Cat[]> {
  return this.catsService.findAll();
}

@Get()
@Roles('admin')
async findAllAdmin(): Promise<Cat[]> {
  return this.catsService.findAllAdmin();
}
Run Code Online (Sandbox Code Playgroud)

换句话说,我希望有两个具有相同 URL 的路由,但通过其他一些值(例如这里的角色)来区分。

我的想法是创建我自己的装饰器,而不是Get,它将填充一些权重图,分配给每个重载方法的唯一路径。然后,添加中间件,它将从请求中获取参数,将它们与 map 进行比较,并进行内部重定向(使用next('route')req.app.handle(req, res))到适当的新路径。

但是在这种方法中,我无法从请求中获取用户,如果他们应该在其中一种方法上使用AuthGuard进行身份验证......

小智 0

它看起来不太好看,但让我们尝试一下。

  1. 创建自定义装饰器
import { createParamDecorator, ExecutionContext } from "@nestjs/common";

export const IsAdmin = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    // Here add the logic to know if is an admin from the request
    return request.role === "admin";
  }
);
Run Code Online (Sandbox Code Playgroud)
  1. 更新您的控制器
@Get()
async findAll(@IsAdmin() isAdmin: boolean): Promise<Cat[]> {
  if (isAdmin) {
    return this.catsService.findAllAdmin();
  }

  return this.catsService.findAll();
}
Run Code Online (Sandbox Code Playgroud)