Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express - better pattern for passing data between middleware functions

I just brought up this issue with Express and I am interested in what StackOverflow thinks about it:

https://github.com/strongloop/express/issues/2831

my question is why Express opts to disallow the developer from passing data directly between middleware functions and basically forces you to assign temporary data to the request object in what I have always considered to be a quite awkward assignment.

to be more specific:

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){}

//now, call the above function

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 ??

perhaps Express already has this capability and I am just misinformed?

like image 261
Alexander Mills Avatar asked Dec 18 '15 00:12

Alexander Mills


People also ask

How do I pass data to next middleware?

The most common pattern for passing variables on to other middleware and endpoint functions is attaching values to the request object req . In your case, that would mean having middlewares such as these: app. use(function (req, res, next) { req.

How many parameters you should pass in the middleware function?

Error-handling middleware always takes four arguments. You must provide four arguments to identify it as an error-handling middleware function.

How do you pass arguments to Express middleware?

Express middleware functions – a quick intro A standard middleware function always follows a signature with the three arguments (req, res, next) where req is the incoming request, res the response to be sent and next a reference to a function for stepping to the next middleware function.

How is an Express middleware added what is it passed?

Middleware functions are functions that have access to the request object ( req ), the response object ( res ), and the next function in the application's request-response cycle. The next function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.


1 Answers

my question is why Express opts to disallow the developer from passing data directly between middleware functions and basically forces you to assign temporary data to the request object in what I have always considered to be a quite awkward assignment.

So I think the API is the way it is to encourage most middleware to be modular, re-usable, and loosely coupled. That means the generally should do something without being concerned too much about what other middleware might run before them or after them. In order to achieve this and create an ecosystem of loosely-compatible middleware functions, express keeps the API fairly generic. There are pros and cons to this. But as a direct answer to your first question, I would say to keep the interface simple, consistent, and flexible as well as try to avoid strict ordering dependencies.

As in your case, there might be implicit dependencies between middlewares. Another common example would be typically your session middleware has an implicit dependency that your cookie middleware runs before it. Having these all be implicit can be argued to create bugs and unnecessary troubleshooting. On the other hand, it enables application developers to more easily mix and match middlewares that might otherwise have no awareness of one another.

In hindsight I think both I as well as some of the express maintainers would agree that using function arity (number of expected arguments) for semantic API reasons was an odd and poor choice on TJ's part. I think if the project were to be rewritten a more explicit API would be defined for error handling.

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

Better - this is highly arguable and opinion based. There is a lot to be said for the simplicity of it and the evidence is the huge ecosystem and usage. There are alternatives available such as hapi, restify, etc, though so you might consider them.

Easier - probably not. What's there is pretty easy.

Faster - probably not in any meaningful way. Not sure why you think your version would be faster, but best to bring metrics when you make such claims.

Stronger - If by "stronger" you mean more explicit that's probably true but there's a reason some people still prefer JavaScript even though TypeScript all the way up through Haskell exist and are definitely "stronger" in some sense of the word.

like image 139
Peter Lyons Avatar answered Oct 03 '22 11:10

Peter Lyons