control order of express/connect middleware

connect.js, express, node.js

Solution

Once you declare a route, Express inserts the `router` middleware into the middleware stack at that point in setting up the app.

In your case, because you insert `.get('/api/test', ...)` before you insert your key checking middleware, the router middleware gets inserted and will take precedence (also for the `/api/data` route you declare later) and your key checker is never called.

Here are two solutions:

// separate middleware, used for all routes that need checking
var keyChecker = function(req, res, next) {
  ...
};
app.get('/api/test', function(req, res) { ... });
app.get('/api/data', keyChecker, function(req, res) { ... });

// or, as an alternative, create a 'catch-all' route between the routes that don't
// need to be checked, and the ones that should; this will also match non-existing
// routes (like '/api/foobar'), which might or might not be an issue;
app.get('/api/test', function(req, res) { ... });
app.all('/api/*', function(req, res, next) { // 'all' means 'all methods'
  // keychecker code
});
app.get('/api/data', function(req, res) { ... });

A third solution could be to explicitly check for `/api/test` in the key checking middleware itself (`req.path === '/api/test'`), and just call `next()` if it matches.

Problem

I'm trying to add authentication middleware that should prevent access to part of the site: ``` app = express() .get('/api/test', function (req, res) { ... }) .use('/api', function (req, res, next) { if (req.param('key')) { next(); } else { res.json(401, { message : 'Authentication failed' }); res.end(); } }) .get('/api/data', function (req, res) { ... }); ``` And my expectation that calls to the /api/data will be first processed by the key checker and then (if it is successful) by the /api/data handler. But instead the request processed by the '/api/data' first. It seems that the checker works for the /api/something_that_does_not_exist, but not for /api/something_that_exist. Maybe I missed something in express/connect documentation? Update I've tracked this up to the fact that the first get/post call initializes the router middleware so it is executed first.

Original source