Connect & Restify CLS Middleware
raw JSON →cls-middleware provides a simple middleware for Connect and Restify (and by extension, Express) to integrate continuation-local storage (CLS) contexts into request handling. It binds each incoming request's execution flow to a dedicated CLS namespace, allowing developers to store and retrieve request-scoped data without explicit parameter passing across function calls. This package relies on the older `continuation-local-storage` library, which itself uses deprecated Node.js internal APIs or earlier experimental `async_hooks` implementations. The current stable version is 1.1.0, published in 2014, indicating it is no longer actively maintained. For modern Node.js environments (v14.5.0+), the built-in `AsyncLocalStorage` is the recommended and more performant solution for managing asynchronous context.
Common errors
error TypeError: Cannot read property 'get' of undefined (or similar 'Cannot read property of null') ↓
app.use(clsify(ns)) is correctly configured and executed, and that the code trying to access CLS is within the execution flow of a request handled by the middleware. Verify the namespace is correctly created. error Error: Cannot set the key "myKey". No CLS context available, please make sure that a ClsMiddleware/Guard/Interceptor has set up the context, or wrap any calls that depend on CLS with "ClsService#run" ↓
ns.bind(callback) to explicitly attach the current context to a callback, or ns.run(callback) to execute code within a new or existing context. Consider using AsyncLocalStorage.snapshot() or AsyncLocalStorage.bind() with modern Node.js APIs. Warnings
breaking This package relies on `continuation-local-storage`, which utilizes older, potentially unstable or deprecated Node.js internal APIs (like `async-listener` or `AsyncWrap`). This can lead to unexpected behavior or compatibility issues with newer Node.js versions. ↓
deprecated The `cls-middleware` package and its core dependency `continuation-local-storage` are no longer actively maintained. The last release was in 2014, and the underlying CLS mechanism has been superseded by `AsyncLocalStorage` in Node.js core. ↓
gotcha CLS context can be lost when integrating with certain third-party middlewares or libraries that do not properly propagate `AsyncResource` contexts, such as `multer` for file uploads or some custom promise-based middleware. ↓
gotcha Incorrect middleware ordering can prevent the CLS context from being established for certain routes or requests. If global prefixes or versioning are used, `cls-middleware` might not trigger on all routes. ↓
Install
npm install cls-middleware yarn add cls-middleware pnpm add cls-middleware Imports
- clsify wrong
import clsify from 'cls-middleware';correctconst clsify = require('cls-middleware'); - cls.createNamespace wrong
import { createNamespace } from 'continuation-local-storage';correctconst cls = require('continuation-local-storage'); const ns = cls.createNamespace('my-namespace');
Quickstart
const cls = require('continuation-local-storage');
const express = require('express');
const clsify = require('cls-middleware');
// Create a CLS namespace for your application
const ns = cls.createNamespace('my-app-namespace');
const app = express();
// Apply the cls-middleware to bind incoming requests to the CLS namespace
app.use(clsify(ns));
app.get('/users', function (req, res, next) {
// Set a request-scoped value
ns.set('userId', req.query.id || 'anonymous');
// Simulate an async operation where the context should persist
setTimeout(() => {
const currentUserId = ns.get('userId');
console.log(`Request ID: ${req.query.id || 'none'} - User ID from CLS: ${currentUserId}`);
res.send(`Hello, User ${currentUserId}!`);
next();
}, 100);
});
// Start the server
app.listen(3000, () => {
console.log('Server listening on port 3000');
});