2

I'm curious about NodeJS and Express. How does middleware actually work? How would I go about creating my own middleware?

Does it rely on a type of Dependency Injection? As I understand you add middleware in the order you want it to be executed, and a HTTP request/response will be passed to the middleware, and onto the next, and next, until one of them returns/renders the request/response.

Are the request and response objects passed through each middleware by reference?

Sorry if this sounds confusing. I'm trying to learn how to create my own middleware to get a better understanding of it in general.

Torra
  • 1,182
  • 5
  • 15
  • 23
  • 1
    You would be better off seeking a forum or some other site that hosts discussions. Stack Overflow is not for asking open ended questions, it's for asking specific questions about problems you're facing, where those problems should normally be able to be solved through a single response with no back-and-forth dialog. – mah Jan 31 '14 at 16:09
  • Simply put, middleware are functions that handle requests. When you create a HTTP server with Node, it can have a stack of middleware associated with it. When a request comes in, it is passed off to the first middleware function, along with a wrapped `ServerResponse` object and a `next()` callback. Each middleware can decide to respond by calling methods on the response object, and/or pass the request off to the next layer in the stack by calling `next()`. – adeneo Jan 31 '14 at 16:14
  • possible duplicate of [What does middleware and app.use actually mean in Expressjs?](http://stackoverflow.com/questions/7337572/what-does-middleware-and-app-use-actually-mean-in-expressjs) – JohnnyHK Jan 31 '14 at 16:31

2 Answers2

3

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.

Evan Hahn
  • 12,147
  • 9
  • 41
  • 59
0

Yes object are always passed by reference in Javascript.

So basically the request and response objects are passed to the first middleware, which do whatever it wants, the request object if it want, and then call next() to trigger the next middleware, which is passed the request and response objects.

When all middleware have returned, response is sent back by the server. (It can be sent before manually.)

If a middleware don't call next() it returns, so for example, if you put your middleware serving static files before more complexes ones, it will return the static files without other middlewares needed to be called.

Your request handler app.get('/index', function(req, res) { /* whatever you want */ }); is itself a middleware.

See for example the source (bottom of page) of the logger middleware from connect : http://www.senchalabs.org/connect/logger.html

jillro
  • 4,456
  • 2
  • 20
  • 26