What does middleware and app.use actually mean in Expressjs?

middleware

I’m halfway through separating the concept of middleware in a new project.

Middleware allows you to define a stack of actions that you should flow through. Express servers themselves are a stack of middlewares.

// express
var app = express();
// middleware
var stack = middleware();

Then you can add layers to the middleware stack by calling .use

// express
app.use(express.static(..));
// middleware
stack.use(function(data, next) {
  next();
});

A layer in the middleware stack is a function, which takes n parameters (2 for express, req & res) and a next function.

Middleware expects the layer to do some computation, augment the parameters and then call next.

A stack doesn’t do anything unless you handle it. Express will handle the stack every time an incoming HTTP request is caught on the server. With middleware you handle the stack manually.

// express, you need to do nothing
// middleware
stack.handle(someData);

A more complete example :

var middleware = require("../src/middleware.js");

var stack = middleware(function(data, next) {
    data.foo = data.data*2;
    next();
}, function(data, next) {
    setTimeout(function() {
        data.async = true;
        next();
    }, 100)
}, function(data) {
    console.log(data);
});

stack.handle({
    "data": 42
})

In express terms you just define a stack of operations you want express to handle for every incoming HTTP request.

In terms of express (rather than connect) you have global middleware and route specific middleware. This means you can attach a middleware stack to every incoming HTTP requests or only attach it to HTTP requests that interact with a certain route.

Advanced examples of express & middleware :

// middleware 

var stack = middleware(function(req, res, next) {
    users.getAll(function(err, users) {
        if (err) next(err);
        req.users = users;
        next();  
    });
}, function(req, res, next) {
    posts.getAll(function(err, posts) {
        if (err) next(err);
        req.posts = posts;
        next();
    })
}, function(req, res, next) {
    req.posts.forEach(function(post) {
        post.user = req.users[post.userId];
    });

    res.render("blog/posts", {
        "posts": req.posts
    });
});

var app = express.createServer();

app.get("/posts", function(req, res) {
   stack.handle(req, res); 
});

// express

var app = express.createServer();

app.get("/posts", [
    function(req, res, next) {
        users.getAll(function(err, users) {
            if (err) next(err);
            req.users = users;
            next();  
        });
    }, function(req, res, next) {
        posts.getAll(function(err, posts) {
            if (err) next(err);
            req.posts = posts;
            next();
        })
    }, function(req, res, next) {
        req.posts.forEach(function(post) {
            post.user = req.users[post.userId];
        });

        res.render("blog/posts", {
            "posts": req.posts
        });
    }
], function(req, res) {
   stack.handle(req, res); 
});

Leave a Comment