Closed mkgn closed 11 months ago
There's multiple things going on in your setup that are wrong, let me go through them one by one:
1) If you're mounting the middleware manually, you need to set mount
to false
. However, in your setup it does not make a difference because you're not passing the options through ClsModule.forRoot
2) I do not understand why you're trying to mount the ClsMiddleware globally and then filter the route inside the setup. If you don't absolutely need to do that because of the order of other middlewares used, I would recommend mounting it in the AppModule instead only to the routes where you need it.
3) Even if you register the middleware manually, you need to register the ClsModule.forRoot
and do not put ClsService
in providers
. It's provided by ClsModule
.
The error you're seeing is caused precisely by this^. The ClsService
has one constructor parameter, which is the AsyncLocalStorage
instace which you don't provide and Nest can't inject it - it's an implementation detail though, you shouldn't ever be putting 3rd party classes into providers
because there's usually more that needs to be set up by the module.
It's like if you were to put CacheService
from @nestjs/cache-manager
directly into the providers
array. It wouldn't work because it needs external setup like the data store configuration, which is done by the CacheModule.register
method, which also in turn provides the CacheService
for injection. The providers
array should only be used for your application's providers - 3rd party ones are usually brought in via a module.
That said, the correct code (in my opinion) should look like this:
@Module({
imports: [
AppSettingsModule,
ClsModule.forRoot({
global: true // <- make ClsService available for injection globally
// alternatively, import `ClsModule` explicitly in modules where it is needed
middleware: {
mount: false // <- do not mount automatically (default, but better to set explicitly)
setup: (context, req: Request, res: Response) => {
context.set(SystemConstants.CurrentContext, new CurrentUserContext());
}
}
})
],
controllers: [AppController],
providers: []
})
export class AppModule implements NestModule{
configure(consumer: MiddlewareConsumer) {
consumer.apply(
ClsMiddleware, // <- mount middleware manually here, settings from module will apply
SwaggerAuthMiddleware
).forRoutes('api');
}
}
If, for some reason, you do need to mount the middleware in main.ts
, you still have to import the ClsModule.forRoot(Async)
to provide the ClsService
.
great! got it to work and thank you!
As per the documentation here I chose to setup using the app.Use method and it looks like below
Then I have registered the ClsService in my AppModule like below
After that I inject the ClsService in one of my guards and use it like below
and at this line const test = this.contextService.get(SystemConstants.CurrentContext) it gives this error Cannot read properties of undefined (reading 'getStore')
I can't figure out any missing configurations I may have done. Btw. I am using FastifyAdapter. So not sure whether it has something to do with it.