Let's say every request to my application contains a MAGIC
header, and I want to inject that header value somewhere, without updating all of my request methods. Sounds like it's a job for middleware, right?
But will this be thread-safe? Is there a way to do this using Express middleware in a world where multiple requests could be in flight at the same time?
In other words, I'm asking if the Express middleware in the example code is setting a global shared variable or if each request is handled by an independent thread where myconfig
is an isolated copy for each single request.
Example code:
var assert = require('assert');
var sleep = require('sleep');
var express = require('express');
var app = express();
var myconfig = {};
app.use(function(req, res, next) {
myconfig.MAGIC = req.headers['MAGIC'];
next();
});
app.get('/test', function(req, res) {
// Pause to make it easy to have overlap.
sleep(2);
// If another request comes in while this is sleeping,
// and changes the value of myconfig.MAGIC, will this
// assertion fail?
// Or is the copy of `myconfig` we're referencing here
// isolated and only updated by this single request?
assert.equal(myconfig.MAGIC, req.headers['MAGIC']);
});
Any middleware function will be executed for each request. When using middleware to set the value of something, it is typically a good idea to set it in app.locals
or res.locals
, depending on how you want the data to persist. Here is a good comparison of the two: https://stackoverflow.com/a/14654655/2690845
app.use(function(req, res, next) {
if (req.headers['MAGIC']) {
app.locals.MAGIC = req.headers['MAGIC'];
}
next();
});
...
app.get('/test', function(req, res) {
assert.equal(app.locals.MAGIC, req.headers['MAGIC']);
});