Express: composing middleware Express: composing middleware express express

Express: composing middleware


This answer is a little late, but here it goes anyway...

// composedMiddleware.jsconst express = require('express')const ware1 = (req, res, next)=>{...}const ware2 = (req, res, next)=>{...}const router = express.Router()router.use(ware1)router.use(ware2)export default router// app.jsconst composedMiddleWare = require('./composedMiddleware.js')app.get('/something', (req, res, next)=>{...})app.get('/something', composedMiddleWare)

If the code isn't self-explanatory, then just note that routers are also middleware. Or, to put it more precisely, "a router behaves like middleware itself, so you can use it as an argument to app.use()" ref.


Glancing through the code for Express (and Connect, on which it is based), it appears that calling use on a piece of middleware does not notify anything in any way, so there's really no way to compose things ahead of time without passing in app.

You could, however, do the composition at run time, e.g. the first time your middleware is called, compose some functions together and cache/call them.


Here's my take:

// app.js...app.use(require('./middleware')());...// middleware.jsvar express    = require('express');    module.exports = function() {  var middleware = [    // list of middleware that you want to have performed:    function mymiddleware(req, res, next) {      console.log('hello world');      next();    },    express.logger('dev'),    express.cookieParser(),    express.static(__dirname)  ];  return function(req, res, next) {    (function iter(i, max) {      if (i === max) {        return next();      }      middleware[i](req, res, iter.bind(this, i + 1, max));    })(0, middleware.length);  };};

If you need access to the app in your custom middleware, you can access it through req.app or res.app.