Middleware Order Matters

Express runs middleware top to bottom, so registration order controls behavior.

Express runs middleware in the order you register it. A middleware only affects routes defined after it. This is the most common source of confusion for beginners.

For example, body-parsing middleware must come before the routes that read req.body. Error-handling middleware must come last so it can catch everything before it.

Example

Example · javascript
app.use(express.json());        // 1. parse JSON bodies first

app.get('/', (req, res) => {    // 2. then routes
  res.send('Home');
});

app.use((req, res) => {         // 3. 404 fallback last
  res.status(404).send('Not found');
});

When to use it

  • A logging middleware must be registered before authentication middleware to capture even rejected requests in the access log.
  • A developer accidentally registers the JSON body parser after the route handler, causing req.body to be undefined, and fixes it by moving app.use(express.json()) above all routes.
  • A catch-all 404 handler is always placed last so it only fires when no other route or middleware has sent a response.

More examples

Correct middleware order

Registers middleware in the correct order: log -> auth -> route -> 404 fallback.

Example · js
const app = require('express')();

app.use((req, res, next) => { console.log('Step 1: log'); next(); });
app.use((req, res, next) => { req.user = { id: 42 }; next(); }); // Step 2: auth
app.get('/', (req, res) => res.json({ user: req.user }));      // Step 3: route
app.use((req, res) => res.status(404).send('Not Found'));       // Step 4: 404

app.listen(3000);

Body parser must come before routes

Illustrates that the JSON body parser must be registered before any route that reads req.body.

Example · js
const express = require('express');
const app = express();

// WRONG: route defined before the parser — req.body is undefined
// app.post('/data', (req, res) => res.json(req.body));
// app.use(express.json());

// CORRECT: parser first
app.use(express.json());
app.post('/data', (req, res) => res.json(req.body));

app.listen(3000);

Early exit skips later middleware

Returns a response without calling next(), so the /data route handler is never reached for unauthenticated requests.

Example · js
app.use((req, res, next) => {
  if (!req.headers['x-api-key']) {
    return res.status(401).json({ error: 'Missing key' }); // stops here
  }
  next(); // only called when key is present
});

app.get('/data', (req, res) => res.send('Secure data'));

Discussion

  • Be the first to comment on this lesson.