Nestjs的上下文
Nest提供了一些应用类来简化在不同应用上下文之间编写应用。这些应用可以用于创建通用的守卫,过滤器和拦截器,可以工作在控制器,方法和应用上下文中。
这一章节就说一下我们之前看过的ArgumentsHost和ExecutionContext两个类.
ArgumentsHost类
ArgumentsHost类提供了获取传递给处理程序的参数。它允许选择合适的上下文(例如HTTP,RPC(微服务)或者Websockets)来从框架中获取参数。框架提供了ArgumentsHost的实例,作为host参数提供给需要获取的地方
ArgumentsHost简单地抽象为处理程序参数。例如,在HTTP应用中(使用@nestjs/platform-express时),host对象封装了Express的[request, response, next] 数组,request是一个request对象,response是一个response对象,next是控制应用的请求响应循环的函数。此外,在GraphQL应用中,host包含[root, args, context, info]数组。
当构建通用的守卫,过滤器和拦截器时,意味着要跨应用上下文运行,我们需要在当前运行时定义应用类型。可以使用 ArgumentsHost的getType()方法。
1 | if (host.getType() === 'http') { |
要获取传递给处理程序的参数数组,使用host对象的getArgs()方法。
1 | const [req, res, next] = host.getArgs();Copy to clipboardErrorCopied |
可以使用getArgByIndex()根据索引获取指定参数:
1 | const request = host.getArgByIndex(0); |
在这些例子中我们通过索引来获取请求响应对象,这并不推荐,因为它将应用和特定上下文耦合
为了使代码更健壮,更可复用,你可以在程序中使用host对象的应用方法来切换合适的应用上下文
1 | /** |
使用 switchToHttp() 方法重写前面的例子, host.switchToHttp()帮助方法调用一个HTTP应用的HttpArgumentsHost对象. HttpArgumentsHost对象有两个有用的方法,我们可以用来提取期望的对象。我们也可以使用Express类型的断言来返回原生的Express类型对象:
1 | const ctx = host.switchToHttp(); |
类似地,WsArgumentsHost和RpcArgumentsHost有返回微服务和WebSockets上下文的方法,以下是WsArgumentsHost的方法:
1 | export interface WsArgumentsHost { |
以下是RpcArgumentsHost的方法:
1 | export interface RpcArgumentsHost { |
ExecutionContext类
ExecutionContext扩展了ArgumentsHost,提供额外的当前运行线程信息。和ArgumentsHost类似,Nest在需要的时候提供了一个ExecutionContext的实例, 例如守卫的canActivate()方法和拦截器的intercept()方法,它提供以下方法:
1 | export interface ExecutionContext extends ArgumentsHost { |
getHandler()方法返回要调用的处理程序的引用。getClass()方法返回一个特定处理程序所属的控制器类。例如,一个HTTP上下文,如果当前处理的是一个POST请求,在CatsController中绑定create()方法。getHandler()返回create()方法和getClass()方法所在的CatsController类的引用(不是实例)。
1 | const methodKey = ctx.getHandler().name; // "create" |
能同时获取当前类和处理方法的引用的能力提供了极大的灵活性。最重要的是,它给我们提供了通过@SetMetadata()装饰器来操作守卫或拦截器元数据的方法(在守卫一节用到过)。
这一节确实没想到能说什么,所以只是把官方文档的内容摘录了一下,没有相关的示例。
之所以有这一节,主要是因为前边守卫、拦截器等都用到了上下文,所以来说一下。