25

for data that only needs to be available during an individual request, where should it be stored? i am creating new properties on the req and res objects so i dont have to pass that data from function to function.

req.myNewValue = 'just for this request'

is the process object an option? or is it shared globally across all requests?

Paul
  • 9,285
  • 6
  • 29
  • 37

4 Answers4

35

In Express 4, the best practice is to store request level variables on res.locals.

An object that contains response local variables scoped to the request, and therefore available only to the view(s) rendered during that request / response cycle (if any). Otherwise, this property is identical to app.locals.

This property is useful for exposing request-level information such as the request path name, authenticated user, user settings, and so on.

app.use(function(req, res, next){
  res.locals.user = req.user;
  res.locals.authenticated = ! req.user.anonymous;
  next();
});

The process object is shared by all requests and should not be used per request.

pxwise
  • 1,350
  • 15
  • 16
  • is it possible that storing user data in `req` would cause interchange of this data with other users (It happens in my case as a very small percentage of users some times find other users' accounts when they login) ? If so, would storing user data in res.locals solves the problem – Ramesh Pareek Mar 23 '18 at 23:23
22

If you are talking about the variable passed like here:

http.createServer(function (req, res) {
    req.myNewValue = 'just for this request';
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(1337, '127.0.0.1');

then it is perfectly fine what you are doing. req stores the request data, you can modify it as you want. If you are using some framework like Express, then it should be fine as well (keep in mind that you may overwrite some built-in properties of req object).

If by "process object" you are refering to the global variable process, then absolutely not. The data here is global and shouldn't be modified at all.

freakish
  • 54,167
  • 9
  • 132
  • 169
  • Indeed, and this is a common idiom--for example check out the [Express docs on Route Middleware](http://expressjs.com/guide.html#route-middleware). – Michelle Tilley Jun 11 '12 at 16:00
  • is it possible that storing user data in `req` would cause interchange of this data with other users (It happens in my case as a very small percentage of users some times find other users' accounts when they login) ? If so, would storing user data in res.locals solves the problem – Ramesh Pareek Mar 23 '18 at 23:24
  • @RameshPareek that should not happen. You may want to open a new so question with your case. – freakish Mar 24 '18 at 06:18
2

If you want to preserve the data across the async callback and there could be scenarios, where request and response objects are not available. So in that case continuation-local-storage package, is helpful.

It is used to access the data or the current express request/response from a point where that is not readily accessible. It use the concept of namespace.

Here is how I set up this

Install the continuation-local-storage package

npm install continuation-local-storage --save

Create namespace

let app = express();
let cls = require('continuation-local-storage');
let namespace = cls.createNamespace('com.domain');

then middleware

app.use((req, res, next) => {
   var namespace = cls.getNamespace('com.domain');
   // wrap the events from request and response
   namespace.bindEmitter(req);
   namespace.bindEmitter(res);

   // run following middleware in the scope of the namespace we created
   namespace.run(function () {
      // set data on the namespace, makes it available for all continuations
      namespace.set('data', "any_data");
      next();
   });
})

Now in any file or function you can get this namespace and use the saved data in it

//logger.ts

var getNamespace = require("continuation-local-storage").getNamespace;
let namespace = getNamespace("com.domain");
let data = namespace.get("data");
console.log("data : ", data);
Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
0

No, it isn't shared along with all requests, it only persists for that request long.

pks
  • 21
  • 3