Using a Middleware
This section applies only if you use a HTTP transport (REST or GraphQL)
Since in NestJS, HTTP middleware is the first thing to run when a request arrives, it is an ideal place to initialise the CLS context. This package provides ClsMiddleware
that can be mounted to all (or selected) routes inside which the context is set up before the next()
call.
All you have to do is mount it to routes in which you want to use CLS, or pass middleware: { mount: true }
to the ClsModule.forRoot()
options which automatically mounts it to all routes.
Once that is set up, the ClsService
will have access to a common storage in all Guards, Interceptors, Pipes, Controllers, Services and Exception Filters that are called within that route.
Automatically
@Module({
imports: [
ClsModule.forRoot({
global: true,
middleware: { mount: true },
}),
],
// ...
})
export class AppModule {}
Manually
Sometimes, you might want to only use CLS on certain routes, or you need to have more control over the order of middleware registration in combination with other middlewares.
In the module
In that case, omit the mount
option or set it to false
and bind the ClsMiddleware
manually in the module:
@Module({
imports: [
ClsModule.forRoot({
global: true,
middleware: { mount: false },
}),
],
// ...
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(ClsMiddleware).forRoutes('custom/route');
}
}
Using app.use
Sometimes, however, the previous method won't be enough, because the middleware could be mounted too late and you won't be able to use it in other middlewares that need to run prior to that - for example, the API versioning feature of NestJS apparently interferes with the order, see issue #67.
In that case, you can mount it directly in the bootstrap method:
function bootstrap() {
const app = await NestFactory.create(AppModule);
// create and mount the middleware manually here
app.use(
new ClsMiddleware({
/* ...settings */
}).use,
);
await app.listen(3000);
}
Please note: If you bind the middleware using app.use()
, it will not respect middleware settings passed to ClsModule.forRoot()
, so you will have to provide them yourself in the constructor.