Compatibility
The table below outlines the compatibility with some platforms:
REST | GQL | WS* | Microservices | |
---|---|---|---|---|
ClsMiddleware | ✔ | ✔ | ✖ | ✖ |
ClsGuard (uses enterWith ) | ✔ | ✔ | ✔ | ✔ |
ClsInterceptor (context inaccessible in Guards and in Exception Filters) | ✔ | ✔ | ✔ | ✔ |
REST
This package is compatible with Nest-supported REST controllers and the preferred way is to use the ClsMiddleware
with the mount
option set to true
.
Tested with:
- ✔ Express
- ✔ Fastify
Known issues:
- In case API versioning is used, the automatic mounting of the
ClsMiddleware
does not work and it needs to be mounted manually. See issue #67 for details. - Some existing Express middlewares may cause context loss, if that happens, mount the
ClsMiddleware
manually after those offending ones (#50)
GraphQL
Using an interceptor or a guard may result in that enhancer triggering multiple times in case there are multiple queries in the GQL request.
Due to this, you should ensure that any operation on the CLS store within enhancers is idempotent. This includes the setup
function. Therefore, it is advised to use the ClsService#setIfUndefined()
method.
Tested with:
- ✔ Apollo (Express)
- ✔ Mercurius (Fastify)
@nestjs/graphql >= 10
Since v10, Nest's GraphQL resolvers are compatible with this package and the preferred way to initialize the CLS context is use the ClsMiddleware
with the mount
option.
@nestjs/graphql < 10
For older versions of graphql, the ClsMiddleware
needs to be mounted manually with app.use(...)
in order to correctly set up the context for resolvers. Additionally, you have to pass useEnterWith: true
to the ClsMiddleware
options, because the context gets lost otherwise due to an issue with CLS and Apollo (sadly, the same is true for Mercurius). This method is functionally identical to just using the ClsGuard
.
Alternatively, you can use the ClsInterceptor
, which uses the safer AsyncLocalStorage#run
(thanks to andreialecu), but remember that using it makes CLS unavailable in Guards.
Others
Use the ClsGuard
or ClsInterceptor
to set up context with any other platform.
There are no explicit test for other transports, so I can't guarantee it will work with your platform of choice, but there's nothing that would indicate otherwise.
If you decide to try this package with a platform that is not listed here, please let me know so I can add the compatibility notice.
Below are listed transports with which it is confirmed to work:
Websockets
Websocket Gateways don't respect globally bound enhancers, therefore it is required to bind the ClsGuard
or ClsInterceptor
manually on the WebsocketGateway
. Special care is also needed for the handleConnection
method (See #8)
@WebSocketGateway()
@UseInterceptors(ClsInterceptor)
export class Gateway {
// ...
}