Is it possible to skip route middleware in node express?

Take the following POST function in express. (I am using express 3.5.1)

app.post('/example', someFunctionOne, someFunctionTwo, function(req, res){ if(!req.someVar){ return res.send(400, { message: 'error'}); } else{ return res.json(200, { message: 'ok'}); } }); 

If I get some result from someFunctionOne, which means someFunctionTwo is redundant, is there a way to skip someFunctionTwo and go to the last unnamed function that will send the response?

So, I think there is also a next () function, where is the last () function? If this is not possible, why not? It seems to me that this is an oversight, but is there a good reason?

+6
source share
4 answers

You can do next('route') , which will go completely to the next route. This is not exactly what you need in this case, but it will work if you break the code into 2 separate routes.

However, I think that, as a rule, there are 2 approaches to this conditional logic:

  • make someFunctionOne put some state in the req instance when it gets a special result, and make someFunctionTwo smart enough to check this and when the next() call is found and bypasses itself. This is the most idiomatic thing to do, and this is how most middleware detects when they are called more than once with the same request and are not redone again.
  • In someFunctionOne , when a special case occurs, just call lastFunction directly. Remember that the abstraction of the middle layer is not the holy grail. If your middleware is so closely related, perhaps they should be one middleware and some supporting functions. There are many other ways to organize your code, which may seem more natural.
+6
source

Probably the best way to do this is to make some kind of helper or put your own middleware in a chain instead of your functions.

So your code will look like this:

 app.post('/example', oneOf(key, someFunctionOne, someFunctionTwo), function(req, res){ if(!req[key]){ return res.send(400, { message: 'error'}); } else{ return res.json(200, { message: 'ok'}); } }); 

And the assistant should be something like this:

 function oneOf (key) { var fns = Array.prototype.slice.call(arguments, 1); var l = fns.length; return function (req, res, next) { var i = 0; function _next () { if (req[key] || i === l) return next(); fns[i](req, res, _next); i += 1; } _next(); } } 

If you decide to do this, the code will look like this:

 app.post('/example', functionOneOrTwo, function(req, res){ if(!req.someVar){ return res.send(400, { message: 'error'}); } else{ return res.json(200, { message: 'ok'}); } }); function functionOneOrTwo(req, res, next) { someFunctionOne(req, res, function () { if (req.someVar) return next(); someFunctionTwo(req, res, next); }); } 

Simple but untested; -)

+1
source

My instinct should do something like this:

 const funcOne = (req, res, next) => { // do something if (/* you were successful */) { res.locals.shouldSkipFuncTwo = true } next() } const funcTwo = (req, res, next) => { if (res.locals.shouldSkipFuncTwo) return next() // do whatever stuff next() } router.get('/', funcOne, funcTwo, (req, res) => { res.status(200).send('hello world') )} 

If you have not used res.locals , here are the express docs . Basically, this is a property in the response object that you can use as a container.

+1
source

Actually, I ran into the same problem. And I just found an express-unless module that does just that: https://github.com/jfromaniello/express-unless

0
source

Source: https://habr.com/ru/post/972498/


All Articles