Search code examples
node.jsexpressmiddleware

After sending response, how to end the current request processing in Node/Express?


There are a few posts on this question but none that answers the issue directly, head-on. Let me clarify that I understand (or so I think) the use of next(), next('route'), return next(), return and their impact on control flow. My entire middleware for the app consists of a series of app.use, as in:

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

In each of these middlewares, I have possibility of sending the response and be done without any need for further processing. My problem is that I am unable to stop the processing from going to the next middleware.

I have a clumsy work around. I just set a res.locals.completed flag after sending a response. In all the middlewares, at the very start, I check this flag and skip processing in the middleware if the flag is set. In the very first middleware, this flag is unset.

Surely, there must be a better solution, what is it? I would think that Express implicitly would do this checking and skip the middlewares through some express-specific method?


Solution

  • According to the express documentation on http://expressjs.com/guide/using-middleware.html

    If the current middleware does not end the request-response cycle,
    it must call next() to pass control to the next middleware,
    otherwise the request will be left hanging.
    

    so if a middleware needs to end the request-response early, simply do not call next() but make sure that the middleware really ends the request-response by calling res.end, res.send, res.render or any method that implicitely calls res.end

    app.use(function (req, res, next) {
      if (/* stop here */) {
        res.end();
      } else {
        next();
      }
    });
    

    Here is an example server showing that it works

    var express = require('express');
    var app = express();
    
    var count = 0;
    app.use(function(req, res, next) { 
      console.log('f1'); 
      next();
     })
    app.use(function(req, res, next) {
      console.log('f2');
      if (count > 1) {
        res.send('Bye');
      } else {
        next();
      }
    })
    app.use(function(req, res, next) {
      console.log('f3');
      count++;
      next();
    })
    
    app.get('/', function (req, res) {
      res.send('Hello World: ' + count);
    });
    
    var server = app.listen(3000);
    

    you will see the after 3 requests, the server shows "Bye" and f3 is not reached