-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Scope Injection (Scope.REQUEST) for global Interceptor, middleware, etc. #1916
Comments
@kamilmysliwiec : Is there a possibility to workaround the constructor injection, by using the service locator pattern within Something like class MyGlobalInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler<unknown>): Observable<unknown> {
const myRequestScopeService =
nestApp.<<<getForCurrentRequest>>>(MyRequestScopeService);
// ...
}
}
nestApp.useGlobalInterceptors(new MyGlobalInterceptor()); |
I am running into this issue. I have a logger service which is request scoped: @Injectable({ scope: Scope.REQUEST })
export class APILoggingService extends APILogger {
constructor(@Inject(REQUEST) request: IAPIGatewayRequest) {
if (
!request ||
!request.apiGateway ||
!request.apiGateway.event ||
!request.apiGateway.context
) {
throw new Error(
'You are trying to use the API Gateway logger without having used the aws-serverless-express middleware',
)
}
super(request.apiGateway.event, request.apiGateway.context)
}
} And I am trying to inject it into a global interceptor like so: @Injectable()
export class LoggingInterceptor implements NestInterceptor {
constructor(private readonly log: APILoggingService) {}
public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const req = context.switchToHttp().getRequest<Request>()
this.log.debug('Incoming Request', new RequestLog(req))
const now = Date.now()
return next.handle().pipe(tap(() => console.log(`After... ${Date.now() - now}ms`)))
}
} Which I have mounted in a module like so: import { APP_INTERCEPTOR } from '@nestjs/core'
import { Module, Provider } from '@nestjs/common'
import { APILoggingService } from './logger.service'
import { LoggingInterceptor } from './logger.interceptor'
const globalRouteLogger: Provider = {
provide: APP_INTERCEPTOR,
useClass: LoggingInterceptor,
}
@Module({
providers: [APILoggingService, globalRouteLogger],
exports: [APILoggingService],
})
export class LambdaModule {} And when ever I hit a route, I get the following error:
|
To add to this, I can confirm that if I use the |
Is a solution planned? |
I'm still seeing this tagged with the question label, I think it should be either categorized as a bug or at the very least a feature request. @kamilmysliwiec |
Yes it would be good to know if it can be implemented or not. |
I tried to find out this problem. But currently cannot be overcome. I had to remove scope.REQUEST and create a service to assign context values from middleware instead of @Inject(REQUEST), before version 6.0 was also the way I handled when recalling the request context. |
Actually, it is supported. Example: {
provide: APP_INTERCEPTOR,
scope: Scope.REQUEST,
useClass: LoggingInterceptor,
} |
@kamilmysliwiec I have the same problem, and when adding the:
It still does not work for me. |
I also can't verify that this works. When I either set I can't spare the time right now to build a minimal example, but I'd be very interested in seeing the disproof of this. Is there an example of request-scoped interceptors working with |
Update: I found time to build that minimal example: https://github.com/eropple/nestjs-request-scope-test Something is really weird here. We know the canonical way to register a global interceptor: app.useGlobalInterceptors(app.get(InterceptorType)); If I attempt to It gets weirder, though, and this is the interesting state of the request-scope-test repo linked above. If you use a It seems like the end solution here is that EDIT: I've tried to get started on a PR to move the ball on this...but |
Further investigation today suggests that request-scoped global interceptors don't and can't work. Unless I'm missing something, it seems like everything that could call them inside the request flow is hard-coded to @kamilmysliwiec, I'm happy to do some of the heavy lifting to address this, but it doesn't appear to be a simple fix and to be productive I need some direction and guidance. Who can help me help myself? |
You obviously cannot use {
provide: APP_INTERCEPTOR,
scope: Scope.REQUEST,
useClass: LoggingInterceptor,
} is supported because it leaves the class instantiation responsibility to Nest. Also, this: app.useGlobalInterceptors(app.get(InterceptorType)); is actually a bad practice, not a canonical way. If you want to bind global enhancers that should live within Nest DI scope, you should use syntax that I shared above. Regarding |
@kamilmysliwiec I try to integrate the context for a GraphQL query into a pipe, as described above, to check the permissibility of individual properties of inputs for the resolvers in relation to the current user: core.module.ts providers: [
{
provide: APP_PIPE,
scope: Scope.REQUEST,
useClass: CheckInputPipe,
}
] But the context is check-input.pipe.ts @Injectable({ scope: Scope.REQUEST })
export class CheckInputPipe implements PipeTransform<any> {
constructor(@Inject(CONTEXT) private readonly context) {}
async transform(value: any, { metatype }: ArgumentMetadata) {
console.log(this.context); ==> undefined
...
} What am I doing wrong? |
@kamilmysliwiec Thanks for the detailed response! I would take some issue with the use of the word "obviously". It's not obvious to me, as a user, why I 100% get you when you say that Also, I'm not having success using I'm sorry to keep pushing, and maybe it's something I'm not understanding, but something still seems really off with this. Can you please take a look and point me (and apparently @kaihaase too) in the right direction? |
This change that I've mentioned:
should fix this confusion soon.
I'll look at both repos asap :) |
@kaihaase @csidell-earny could you please test this in 6.5.0? Errors should be gone now |
I'm neither of those folks, but my test app exhibits the expected behavior now. Thanks, @kamilmysliwiec! :) |
I can confirm that my interceptor is now able to inject a dependency and it is working as expected. Thank you very much! |
@kamilmysliwiec Did you accidentally tag me on this one? |
@kamilmysliwiec After updating to 6.5.0, the transform method of my pipe is no longer called. |
@csidell-earny ahh yeah sorry, I actually wanted to tag @eropple 😄 |
@kaihaase we should create a separate issue in the github repo. In order to support this functionality by |
@kamilmysliwiec I created a separate issue in the repo of @nestjs/graphql: nestjs/graphql#325 |
Thank you :) |
I wonder if it is possible to initialize pipe after run guard? |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
I'm submitting a...
Current behavior
example:
main.ts
MultiTenancyHTTP.interceptor.ts
Expected behavior
Support Scope Injection (Scope.REQUEST) for global Interceptor, middleware, etc.
Environment
The text was updated successfully, but these errors were encountered: