我正在NestJS中开发一个个人项目,用于学习目的。目前我正在将Swagger集成到其中。因此,假设我想展示某个路由可能给予UnauthorizedException
作为响应。我自然必须这样做
@ApiUnauthorizedResponse({ description: 'Unauthorized' })
@Get()
findAll() {
return this.usersService.findAll();
}
但是,我想把这个装饰器添加到所有非公共的路由中,所以,在一个拦截器中,我会得到当前的路由处理器和isPublic
元数据,从这些中,我想决定是否把装饰器添加到处理器引用中,但是如果可能的话,我该怎么做呢?
现在,我想象拦截器是这样的。请不要考虑拦截器的名字,它不是最终的。
@Injectable()
export class UnauthSwaggerInterceptor implements NestInterceptor {
constructor(private readonly reflector: Reflector) {}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const handler = context.getHandler();
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC, [
context.getHandler(),
context.getClass(),
]);
if (!isPublic) {
// Apply Swagger decorator to handler
}
return next.handle();
}
}
因此,如图所示,我将首先获取对当前处理程序的引用,该处理程序的类型为Function
。
然后,使用reflector
从路由中获取isPublic
元数据。
然后,验证路由是否是公共的,以便应用装饰器。我使用公共装饰器将路由标记为公共的。
export const IS_PUBLIC = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC, true);
所以,我想把前面提到的Unauthorized response的decorator附加到这个特定的非公共处理器上。有可能这样做吗?因为它不是函数声明,它是一个将在运行时获得的引用。在肯定的情况下,那么正确的操作过程是什么?
我不知道是否有一种方法可以直接将装饰器应用到函数中。虽然装饰器只能应用到类的上下文中,但我想只将它应用到控制器方法中。据我所知,Nest的Swagger插件基本上就是这样做的,它根据特定的规则动态地添加装饰器。如果可能的话,这也是我想实现的。
2条答案
按热度按时间hmtdttj41#
在运行时尝试更新装饰器是没有意义的。装饰器的存在是为了在服务器启动时,可以在运行时执行或读取某些操作。对于swagger装饰器,这些都是在服务器启动时通过
SwaggerModule
的createDocument
方法读取的。即使您在请求时更改它们,您不会修改当前的swagger,并且它在服务器重启后也不会持续。2exbekwf2#
装饰器只是一个被装饰者调用的函数(尽管这里我们有TS手册中所称的装饰器工厂):
这个打印出来
正如你所想象的。
哦,
约等于
你可以想象用一个变量代替
Injectable()
保存一个函数。