139

There are some similar questions asked but my question is that if I want to propagate intermediate results that I get along the different routing middleware, what is the best way to do that?

app.use(f1); app.use(f2); app.use(f3);

function f1(req,res,next) {
  //some database queries are executed and I get results, say x1
  res.locals.dbResults = {...};
  next();
}

function f2(req,res,next) {
  // more processing based upon req.locals.dbResults 
  res.locals.moreResults = {....};
  next();
}
// ...

I think that I can get the same propagation of data through the different middleware by using req.locals. Also, it appears that the request and response objects both have the locals properties initialized to an empty object at the start of the request.

Also, one can set res.mydata or req.mydata properties too?

In theory, app.locals can also be used for passing this data along through the different middleware as it will persist across middlewares but that would be contrary to the conventional use of app.locals. It is used more for application specific data. It will also be necessary to clear that data at the end of the request-response cycle so the same variables can be used for the next request.

What is the optimal and standard way to propagate intermediate results through middleware?

Sébastien
  • 11,860
  • 11
  • 58
  • 78
Sunny
  • 9,245
  • 10
  • 49
  • 79

2 Answers2

214

As you mentioned, both req.locals, res.locals or even your own defined key res.userData can be used. However, when using a view engine with Express, you can set intermediate data on res.locals in your middleware, and that data will be available in your view (see this post). It is common practice to set intermediate data inside of middleware on req.locals to avoid overwriting view data in res.locals, though this is not officially documented.

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.

Source: http://expressjs.com/en/api.html#res.locals

Ezra Chu
  • 832
  • 4
  • 13
xaviert
  • 5,653
  • 6
  • 29
  • 31
  • 1
    Thanks for the clarification on the documentation distinction which works in favor of res.locals. You confirmed my understanding that in theory all approaches are technically the same. Lets wait for more comments. Upvoted your answer... certainly useful. – Sunny Oct 31 '15 at 13:39
  • 1
    Side note: `res.render()` take precedence over `res.locals`. So someone could _accidentally_ overwritten the variable like so ```res.locals = { name: 'Jake' } // later in code... res.render('user.template', { name: 'Tony' }, (err, html) => {}) // the 'name' variable is now 'Tony'``` – zenoh Sep 01 '20 at 14:03
  • 2
    Anyway, well planned, clean and modular middleware design should be the better and long term solution than just relying on a single object key – zenoh Sep 01 '20 at 14:12
  • 1
    req.locals (at least in typescript) doesn't appear to exist any longer, So i'm wondering if its now advised to use res.locals and not use req.locals at all? – Emile Mar 30 '22 at 17:41
  • 1
    IMO, because API caller can manipulate req.locals from request call, so better put the intermediate result in res.locals – Yosua Lijanto Binar Aug 01 '22 at 04:57
  • 1
    dont IMO, how @YosuaLijantoBinar can the caller modify req.local; it would render req.locals unsafe for route handler data passing. – droid192 Dec 12 '22 at 16:03
1

I didn't come across req.locals while reading the express documentation,I don't even think it exists.

What I would advice is that use res.locals for storing data that's going to be rendered in your views.

If you want to store custom data,create a property(preferably array or object) inside res or req instances eg req.data={},then store your data inside this "object".

Da da
  • 11
  • 2
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 16 '23 at 07:32