Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExpressJS Middleware req, res, next scope

After studying some Middleware's I have still a question.

Have a look at the following working setup, It just attaches the do it function to the req object so that we can call it in any route just like req.doit()

But where does the req, res, next come from ?, I never passed them and I am even more curious how it works since the anonymous function (2.) is surrounded by another function (1.) which I even can pass arguments.

MiddleWareTest.js:

var test = function(options){ //1.)
    return function(req, res, next) { //2.)
        req.doit = function() {
            console.log('doit')
        }
        next();
    }
}
module.exports = test;

app.js:

...
var myMiddleware =  require('./MiddlewareTest.js')
app.use(myMiddleware())
...

Any suggestions to deepen my knowledge are welcome :)

~Marc

like image 971
daslicht Avatar asked Aug 20 '13 10:08

daslicht


2 Answers

Remember functions are objects in JS, so they can be passed around and returned like any other object.

When you tell express to use your middleware, you are calling the myMiddleWare function:

app.use(myMiddleWare());

this call returns the anon function you labelled as \\2.. Express.js will then call it as part of it's middleware stack when processing a request, giving it the req, res and next arguments.

You can always see which arguments are passed to a function by inspecting the arguments object. (i.e. console.log(arguments));

like image 171
radiodario Avatar answered Sep 21 '22 05:09

radiodario


The parameters (req, res, next) are passed to it when express runs through the middleware chain. Assume that app.use is a (more complicated) version of this:

app.use = function(middleware){
  middlewareChain.push(middleware);
}

When a request arrives, express runs through the middleware chain, start to finish. The first defined piece of middleware is called, with the current req, res, and next, where next is the next piece of middleware in the chain.

At the end of the chain, next is just an empty function. Hopefully, by that point, you've done something with the res object (like res.send).

(2) is surrounded by an anonymous function so that you can pass options in your call to app.use. For example, connect's cookieParser accepts a cookieSecret. If you're developing middleware that has no options, it's acceptable (but inconsistent) to define it with the arity (req, res, next) and skip returning a function. In that case, you could simply write app.use(myMiddleware).

ExpressJS Docs on Middleware

like image 33
ssafejava Avatar answered Sep 21 '22 05:09

ssafejava