Created: June 26, 2016

Talking with a collegue of mine I came up with this solution about organizing the code in NodeJS+Express using middlewares.

Consider this example in which we have a simple page that performs two queries and shows the result in a template.

Since everything is asynchronous, we chain in two queries in this way

app.get('/mypage', function(req,res,next) {
  sequelize.search(query1)
    .on('success', function(res_query1) {
      sequelize.search(query2)
        .on('success', function(res_query2) {
          res.render('my_template', {
            query1: res_query1, query2: res_query2
           });        });    });});

There's nothing wrong with this, the only problem is that as long as the page gets new functionalities, you keep nesting queries and asynchronous callback.

The resulting code could become unreadable after few cycle of releases.

The app.get() accepts any combination of middlewares and arrays of middlewares, each one carrying the same instance of req object (that means we can use it to store temporary result...).

So we could split everything in middlewares using the rule of thumb that only the last middleware is allowed to speak with the rest of the world

app.get('/mypage',  
  (req, res, next) => {
    sequelize.search(query1)
      .on('success', res_query1 => {
        req.query1 = res_query1;        
        return next();      
      });  
  },  
  (req,res,next) => {
    sequelize.search(query2)
      .on('success', res_query2 => {
        req.query2 = res_query2;        
        return next();      
      });  
  },  
  (req, res, next) => {
    res.render('my_template', {
      query1: req.query1,      
      query2: req.query2    
    });  
  }
);

Basically every middleware performs a single step in our asynchronous operations, saving the result in the req object (used like a stack for temporary result) and, finally, calling return next(): don't forget this, it passes the control to the next middleware (otherwise the browser call will hang up until time out).

So far it's just a way of writing the same thing in a different manner. But suppose that, at some point, you want to be able to update the first query via AJAX without reloading the whole page.

We don't want for replicate piece of codes, so we just assign the first two middlewares to variables (for example mw_1 and mw_2) and detach the part of the template that renders query1 into a sub-template (called within my_template).

After this code reorganization, it's super easy

app.get('/mypage/ajax', mw_1, mw_2, (req, res, next) => {
  res.render('my_subtemplate', { query1: req.query1 });
});

The front-end code (not relevant for this example) just have to put the resulting piece of HTML in the right place.

We added functionality without duplicating functionality and without messing up the organization of the code.

Welcome middlewares!