Edit: This post was written for Express 3. Minor details have changed since then, but it's conceptually the same.
A note before I start: Express is built atop Connect, which basically handles its middleware. When I write express
in these examples, I'd just as easily be able to write connect
.
At the bottom level, you have Node's HTTP server module. It looks kind of like this:
var http = require("http");
http.createServer(function(request, response) {
response.end("Hello world!\n");
}).listen(1337, "localhost");
Basically, you make a single function that handles all HTTP requests. Try running the above code and visiting localhost:1337/hello or localhost:1337/wow-anime. Technically, this is all you really need!
But let's say you want many functions to run every time. Maybe you want to add a command-line logger, and maybe you want to make every request plain text.
var http = require("http");
http.createServer(function(request, response) {
// logger
console.log("In comes a " + request.method + " to " + request.url);
// plain text
response.writeHead(200, { "Content-Type": "text/plain" });
// send response
response.end("Hello world!\n");
}).listen(1337, "localhost");
In Express/Connect, you might write this instead:
var express = require("express");
var app = express();
app.use(express.logger());
app.use(function(request, response, next) {
response.writeHead(200, { "Content-Type": "text/plain" });
next();
});
app.use(function(request, response) {
response.end("Hello world!\n");
});
app.listen(1337);
I think of middlewares as a list of functions. When an HTTP request comes in, we start at the top and go through each middleware from top to bottom, and we stop when response.end
is called (or response.send
in Express).
I wrote a blog post that explains Express and middleware in more detail, if you're interested.