Node.js
Middleware
Add logging, error and validation middleware.
Middleware
Middleware is a function that runs before every request. For example, a middleware that logs the request method records all incoming requests. In Express it is registered with app.use(fn); fn takes three parameters: (req, res, next).
When done you call next(); this passes control to the next middleware or route. If next is not called the request hangs. Example: (req, res, next) => { console.log('Request: ' + req.method); next(); }. You can collect several middlewares in an array and register them one by one with app.use(middleware[0]). You print the count with middleware.length.
The middleware array
Keeping several middlewares in an array makes it easy to control their order. You define const middleware = [] and add with middleware.push(fn). Then you register it with Express via app.use(middleware[0]).
The first middleware logs the request method: middleware.push((req, res, next) => { console.log('Request: ' + req.method); next(); }). You register it with app.use(middleware[0]). You print the count with console.log('Middleware: ' + middleware.length). The array lets you manage the order and count of middlewares in one place. To add a second middleware later, you push it and register with app.use(middleware[1]).
Exercise Add middleware
Define const middleware = []. Add middleware.push((req, res, next) => { console.log('Request: ' + req.method); next(); }). Register with app.use(middleware[0]). Print console.log('Middleware: ' + middleware.length).
Show example solution
const express = require('express');
const app = express();
const routes = [];
app.get('/health', (req, res) => res.json({ok: true}));
routes.push({method: 'GET', path: '/health'});
console.log('Server ready');
app.get('/users', (req, res) => res.json([]));
routes.push({method: 'GET', path: '/users'});
app.post('/users', (req, res) => res.json({created: true}));
routes.push({method: 'POST', path: '/users'});
console.log('Routes: ' + routes.map(r => r.method + ' ' + r.path).join(', '));
const fs = require('fs');
const DB_PATH = '/tmp/nodejs-i20.json';
function saveUsers(data) {
fs.writeFileSync(DB_PATH, JSON.stringify(data));
}
function loadUsers() {
return JSON.parse(fs.readFileSync(DB_PATH, 'utf8'));
}
saveUsers({users: ['Ayşe', 'Alex']});
console.log('Loaded: ' + JSON.stringify(loadUsers()));
const middleware = [];
middleware.push((req, res, next) => { console.log('Request: ' + req.method); next(); });
app.use(middleware[0]);
console.log('Middleware: ' + middleware.length);
Test yourself
-
What happens if next() is not called?
(req, res, next) => { console.log(req.method); }
- The request is answered immediately
- The server crashes
- The request hangs
- Throws an error
Show answer
The request hangs — Without next() the request hangs; control never reaches the route handler.
-
Match each piece to its role
- app.use
- Registers middleware
- next()
- Passes to the next
- req.method
- The request method
- middleware.push
- Adds middleware to the array
-
Complete the app.use line
app.____(middleware[0]);
Show answer
app.use(middleware[0]);
Next lesson: Putting it together