Search code examples
node.jsexpresscallbacknode-async

Why calling next() in express routes is optional?


In many examples of Nodejs/Express, I see that calling next() is optional in case of success.

 exports.postLogin = (req, res, next) => {
  passport.authenticate("local", (err, user, info) => {
    if (err) {
      return next(err);
    }
    req.logIn(user, err => {
      if (err) {
        return next(err);
      }
      req.flash("success", { msg: "Success! You are logged in." });
      res.redirect(req.session.returnTo || "/");
    });
  })(req, res, next);
};

Also, it is easy to skip callback next in the args:

exports.postLogin = (req, res) => {
   res.render('some-template', locals);
}

If I compare this with async lib or typical Javascript's asynchronous model, a missing callback will not give data or halt the process.

What does express do to take care of control flow when next is not called?


Solution

  • The true callback in an Express middleware chain isn't actually next, as you might assume, but res.end(). Any request that is handled must, at some point, call this function (either directly or indirectly) to say that the request has been handled.

    When you call next() in your middelware, you're passing on the responsibility of calling res.end() to the middleware further down the middleware chain. If the last middleware in the chain calls next(), then Express knows that no middleware has or will handle the request, and so a "404 Not Found" page will be generated.


    Also, calling next(err) with a single argument err works differently, because it tells Express that an error occured and that it should instead by handled by the error handler.