better pattern for passing data between middleware functions

Hey all

I am pretty well versed with Express and have been using it for more than a year…

passing data between middleware functions usually involves doing this

req.specialData = {}
next();

however, it would be perhaps much easier and more performant (!) if this were possible

next(null,data);

or

function mySpecialMiddleWare(req,res,next,data){}

//call the above

mySpecialMiddleWare(req,res,next, {some:data});

the problem is that Express uses a, what I believe to be, stupid way of determining if the call is to a normal middleware function or the next error first middleware function, by checking to see if the function.length > 3 or function.length = 4…

is there any chance what I am saying makes any sense?

wouldn’t it be better/easier/faster/stronger to allow direct passing of data via middleware functions instead of assigning data awkwardly to req ??

very curious what you say, thanks

Author: Fantashit

4 thoughts on “better pattern for passing data between middleware functions

  1. @ORESoftware The request object is used for context about the request. More than one thing middleware can contribute to the context. This practice isn’t really equivalent to using a callback to pass data around. To do what you’re proposing, every middleware would need to opt-in and append to it and you’d probably end up with the same practice – everyone contributing context to a single object. Data itself shouldn’t be passed in this pattern, since you generally do the query once and respond in a single handler (E.g. you’re doing a database query and sending a response based on context, not contributing to the context itself).

    As for checking if the first argument is an instanceof of an error. Common practice in node is for the first argument to be an error, it doesn’t have to specifically be an error instance – just not falsy – to indicate an error. Using the instanceof behaviour would break users expectations.

  2. Look, I am just trying to make an argument, please don’t think I am criticizing you personally, and please be less defensive.

    I don’t agree with what you’re saying. I have two separate arguments:

    (1) Express error handling middleware is not implemented correctly (IMO)
    (2) You should be able to call next(null, {}) and have the second argument passed directly to the next middleware function

    this do not seem like wild claims to me, and I doubt they can be easily dismissed, and they are independent claims.

    On point (1)

    What I am saying is that if a function has this signature:

    function(err){
    
    }

    then it should be considered error middleware, but as it stands, it is not considered as proper middleware. if the above function is in the middleware chain, it should not be ignored.

    So here’s where shit gets weird and unexpected

    this is considered proper middleware

    function(req,res); (without the next arg)

    but this is not proper error middleware

    function(err,req,res);

    you need that next argument like so

    function(err,req,res, next);

    which is totally surprising, right? That is surprising!

    if you call

    next(new Error(‘foo’));

    or

    next(‘foo error’);

    this point doesn’t matter – as long as it’s a defined/non-null value, we assume it’s an error and we invoked the next error handler – we can obviously distinguish an Error object with instanceof Error, but let’s assume that we will want to pass any non-null object as an argument to an error-first function.

    on point (2)

    you are probably right about it requiring less memory, but yes it might take a proper test to determine that

  3. Look, I am just trying to make an argument, please don’t think I am criticizing you personally, and please be less defensive.

    An argument would need some thought or proof, you haven’t provided any yet. I didn’t make any note about you being criticising, just trying to point out the facts which you keep ignoring here.

    (1) Express error handling middleware is not implemented correctly

    What’s not correctly implemented?

    (2) You should be able to call next(null, {})

    Why? Please provide some logic before you ask for something. Most likely you’re doing something wrong if you feel like you need this. And no one will help because you just keep repeating the same thing without any reasoning.

    then it should be considered error middleware

    Error middleware must have four arguments, it’s well documented.

    if the above function is in the middleware chain, it should not be ignored.

    It’s not ignored. According to the rule above, functions that don’t have four arguments are regular middleware functions. So it’s become a normal middleware function.

    So here’s where shit gets weird and unexpected

    It’s not weird or unexpected. See rule above. Does the function have four arguments? Yes/no, that’s your answer. Maybe it could be improved, but there needs to be a better solution. I’ve already pointed out your solution does and will not work.

    as long as it’s a defined/non-null value, we assume it’s an error and we invoked the next error handler

    That’s exactly how it works today. You were asking for something else. It sounds like your confused by how arguments work, and they aren’t magical. See the rule above. That’s how an error is handled, they value of the error is never checked against (which is what you were asking for in the previous comment). The fact that your first argument is called err, error, foo, bar, req, etc. is just an implementation detail for your own sanity and does not affect Express.

  4. why not use the res.locals property to store data that can be passed between all of the middlewares that happen to serve the request?

Comments are closed.