Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Express 将类似中间件的机制应用于解析器&x27;查询和突变_Express_Nestjs - Fatal编程技术网

Express 将类似中间件的机制应用于解析器&x27;查询和突变

Express 将类似中间件的机制应用于解析器&x27;查询和突变,express,nestjs,Express,Nestjs,我正在使用Nest框架构建一个GraphQLAPI,并试图将第三方express中间件(和)实现到一些查询和变体中 问题是所有graphql突变和查询都使用相同的端点,所以我不能明确地告诉您中间件应该应用于哪个查询或突变,因为您只能使用路由路径(在整个API中都是相同的)来实现这一点 从'@nestjs/common'导入{Module,NestModule,MiddlewareConsumer,RequestMethod} 从“快速费率限制”导入*作为费率限制 从“利率限制redis”导入*作

我正在使用Nest框架构建一个GraphQLAPI,并试图将第三方express中间件(和)实现到一些查询和变体中

问题是所有graphql突变和查询都使用相同的端点,所以我不能明确地告诉您中间件应该应用于哪个查询或突变,因为您只能使用路由路径(在整个API中都是相同的)来实现这一点

从'@nestjs/common'导入{Module,NestModule,MiddlewareConsumer,RequestMethod}
从“快速费率限制”导入*作为费率限制
从“利率限制redis”导入*作为Redistore
从“redis”导入{RedisClient}
@模块({
提供者:[],
出口:[],
})
导出默认类SecurityModule实现NestModule
{
构造函数(受保护的只读redisClient:redisClient)
{
}
配置(消费者:MiddlewareConsumer)
{
消费者申请(
新差饷限额({
最高:300,
windowMs:15*60*1000,
存储区:新的RedisStore({client:this.redisClient}),
})).forRoutes({path:'/graphql',method:RequestMethod.ALL})//这将中间件应用于所有查询和突变
}
}
所以我试着同时使用警卫和拦截器,但是失败了

这是一次失败,原因很明显。
错误:发送头后无法设置头。
被抛出

/*!!!我的拦截器想要完全相同的*/
从“@nestjs/common”导入{ExecutionContext,可注入,可激活}
从“快速减速”导入*作为速度限制
从“express”导入{Request,Response}
@可注射()
导出默认类SpeedLimitGuard实现CanActivate
{
建造师(
受保护的只读选项:speedLimit.options,
) {
}
async canActivate(上下文:ExecutionContext):承诺{
const{req,res}:{req:Request,res:Response}=context.getArgs()[2]
速度限制({…this.options})(req、res、req.next)
返回真值
}
}
从'@nestjs/common'导入{NestInterceptor,ExecutionContext,可注射,INestApplication,INestExpressApplication}
从“rxjs”导入{observatable}
从“快速减速”导入*作为速度限制
//从“express”导入{Request,Response}
从'@nestjs/core'导入{ApplicationReferenceHost}
从“redis”导入{RedisClient}
从“利率限制redis”导入*作为Redistore
@可注射()
导出默认类SpeedLimitInterceptor实现NestInterceptor
{
构造函数(私有只读appRefHost:ApplicationReferenceHost,
私有只读redisClient:redisClient,)
{}
拦截(上下文:ExecutionContext,调用$:可观察):可观察
{
//const{req:request,res:response}:{req:request,res:response}=context.getArgs()[2]
const httpServer=this.appRefHost.applicationRef
常量应用程序:INestApplication&INestExpressApplication=httpServer.getInstance()
应用程序使用(速度限制)({
延迟时间:1,
商店:新商店({
前缀:“测试”,
客户:这是我的客户,
}),
}))
应用程序使用((请求、恢复、下一步)=>{
log('is middleware triggered',{req,res})
下一个()
})
回电$
}
}

有没有办法将第三方express中间件明确地应用于GraphQL变异/查询?

因此,从底层来看,守卫正在工作,因为我是可以证明这一点的活生生的人类bean:

@Query('getHome'))
@UseGuards(GraphqlGuard)
异步findOneById(@Args('id')id:string):承诺{
返回等待此.homeService.findOneById(id);
}
它只是在工作

这是
GraphqlGuard.ts

从'@nestjs/common'导入{ExecutionContext,Injectable};
从'@nestjs/graphql'导入{GqlExecutionContext};
从'@nestjs/passport'导入{AuthGuard};
从'@nestjs/core/helpers/executioncontext.host'导入{ExecutionContextHost};
从“rxjs”导入{Observable};
@可注射()
导出类GraphqlGuard扩展了AuthGuard('jwt'){
canActivate(上下文:ExecutionContext):布尔值|承诺|可观察{
const ctx=GqlExecutionContext.create(context);
const{req}=ctx.getContext();
返回super.canActivate(新的ExecutionContextHost([req]);
}
}
但是要使用上下文,必须让它为您工作,因此,无论您在哪里传递graphql配置,都会有一个上下文
回调
,对我来说,它是这样的:

context:(context)=>{
设req=context.req;
if(context.connection){
req=context.connection.context.req;
}
返回{req};
}
我在这里检查来自websocket的上下文连接。我用的是全球拦截器,所以它们工作起来很有魅力。但是您仍然可以使用
@UseInterceptors(SomeInterceptor)
decorator,它也可以工作。顺便说一句,在最后,我不需要任何防护、管道、验证器和拦截器,对我来说已经足够了


尊敬。

您能分享一下拦截器的实现吗?这将是解决此问题的正确嵌套组件类型problem@JesseCarter我在我的帖子编辑中加入了摘录。它不起作用,我明白为什么。我只是不知道应该如何正确地实现它。我认为在拦截器中添加的中间件永远不会被触发,因为-我怀疑-在应用程序生命周期中注册中间件已经太晚了,但我不能确定。据我所知,应用程序的生命周期是:中间件->守卫->拦截器->管道,所以在拦截器中注册中间件看起来是个坏主意。中间件实际上只是一个功能