title: How to make dynamic chain of middleware in express.js
body: <p>I am currently working on a project to develop an API manager to control an existing API.</p>
  
  <p>It contains a list of "before" and "after" middlewares, which are used to do things like security checking and logging. And a "service" middleware to do http request to the existing API. But the problem is that I want to make the order the middleware being executed to be dynamic, meaning that I could load some configuration file to change the order the middleaware get executed every time the request comes in.</p>
  
  <p>here is my previous code:</p>
  
  <pre><code>'use strict';
  // Loading the express library
  var express = require('express');
  var app = express();
  
  var service = require('./routes/index');
  
  
  // Testing configurable middleware
  var confirguration = {
      before1: {
          priority: 100,
          enable: true
      },
      before2: {
          priority: 80,
          enable: true
      },
      service: {
          priority: 50,
          enable: true
      },
      after1: {
          priority: 30,
          enable: true
      },
      after2: {
          priority: 10,
          enable: true
      }
  }
  
  var before1 = require('./example_middleware/before1');
  var before2 = require('./example_middleware/before2');
  var after1 = require('./example_middleware/after1');
  var after2 = require('./example_middleware/after2');
  // Fake request to simulate the /service
  var fakeRequest = require('./example_middleware/fake_request');
  
  // Function to sort the order of the middleware to be executed
  var sortConfig = function(confirguration){
      var sortable = [];
      for (var middleware in confirguration)
          // To make middlewares configurable
          if (confirguration[middleware]['enable'] == true){
              sortable.push([middleware, confirguration[middleware]['priority']]);
          }
  
      sortable.sort(function(a, b) {return b[1] - a[1]});
      return sortable;
  }
  
  // var sortedConfig = [];
  var middlewareSet = new Array();
  app.use('/test', function(request, response, next){
      var middleware;
      var sortedConfig = sortConfig(confirguration);
  
      for (var i in sortedConfig){
          switch(sortedConfig[i][0]){
              case 'before1':
                  middleware = before1;
                  break;
              case 'before2':
                  middleware = before2;
                  break;
              case 'service':
                  middleware = fakeRequest;
                  break;
              case 'after1':
                  middleware = after1;
                  break;
              case 'after2':
                  middleware = after2;
                  break;
          }
  
  
          // console.log(sortedConfig[i][0]);
          // Execute the middleware in expected order
          middlewareSet.push(middleware);
      }
      // request.sortedConfig = sortedConfig;
      console.log(middlewareSet);
      console.log('middleware list sorted');
      next();
  });
  
  app.use('/test', middlewareSet);
  </code></pre>
  
  <p>But I keep getting the same error message coming from the app.use() at the last line:</p>
  
  <blockquote>
    <p>app.use() requires middleware functions</p>
  </blockquote>
  
  <p>It works if I use:</p>
  
  <pre><code>app.use('/test', [before1, before2, fakeRequest, after1, after2]);
  </code></pre>
  
  <p>But it's not dynamic though, what did I misunderstand? There must be a way to do this in express.js.</p>
  
  <p>Thanks in advance.</p>
  
  <p><strong>EDIT:</strong>
  I modified my code according to Ryan's answer, here is the code:</p>
  
  <pre><code>var async = require('async');
  app.use('/test', configurableMiddleWare);
  
  function configurableMiddleWare(req, res, next) {
  
      var operations = [];
  
      var middleware;
  
      var sortedConfig = sortConfig(confirguration);
  
     // push each middleware you want to run
      sortedConfig.forEach(function(fn) {
  
          switch(fn[0]){
              case 'before1':
                  middleware = before1;
                  break;
              case 'before2':
                  middleware = before2;
                  break;
              case 'service':
                  middleware = fakeRequest;
                  break;
              case 'after1':
                  middleware = after1;
                  break;
              case 'after2':
                  middleware = after2;
                  break;
          }
  
          operations.push(middleware); // could use fn.bind(null, req, res) to pass in vars  
      });
  
      console.log('middleware list sorted');
     // now actually invoke the middleware in series
      async.series(operations, function(err) {
          if(err) {
          // one of the functions passed back an error so handle it here
              return next(err);
          }
        // no errors so pass control back to express
          next();
      });
  
  }
  </code></pre>
  
  <p>Just to make sure I haven't made any mistakes in my test middleware, here is an example of one of them:</p>
  
  <pre><code>'use strict';
  
  var express = require('express');
  var router = express.Router();
  
  router.route('/')
      .all(function(request, response, next){
          console.log('This is middleware BEFORE1');
          next();
      });
  
  
  module.exports = router;
  </code></pre>
  
  <p>Now, when I run my application, I got the following error from npm:</p>
  
  <blockquote>
    <p>TypeError: Cannot call method 'indexOf' of undefined</p>
    
    <blockquote>
      <p>at Function.proto.handle (/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/express/lib/router/index.js:130:28)
         at router (/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/express/lib/router/index.js:35:12)
         at /Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:610:21
         at /Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:249:17
         at iterate (/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:149:13)
         at async.eachSeries (/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:165:9)
         at _asyncMap (/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:248:13)
         at Object.mapSeries (/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:231:23)
         at Object.async.series (/Users/jialunliu/Documents/SOA_project/FAT-LADY/node_modules/async/lib/async.js:608:19)
         at configurableMiddleWare (/Users/jialunliu/Documents/SOA_project/FAT-LADY/app.js:135:11)</p>
    </blockquote>
  </blockquote>
  
  <p>Which is coming from the line
  <code>async.series(operations, function(err){})</code></p>
  
  <p>I am keep getting this kind of error message, saying the function could not read from this array of functions "operations"....</p>