CodingNic

Middleware

Exercises

Middleware 30 min read

Exercises

Objectives

By the end of this lesson, you should be able to:

  • Wire up a complete, realistic middleware stack in one Express app
  • Write and apply custom middleware alongside third-party middleware
  • Explain, for a given piece of middleware, what it does and why it’s ordered where it is

⚠️ A note on verification: every command and output in this lesson was actually run with Express.

Exercise: A Fully-Equipped Express App

a) Install everything. In a fresh project, install express, morgan, helmet, cors, cookie-parser, and compression.

b) Register the standard stack. In this order, register: morgan('dev'), helmet(), cors(), compression(), express.json(), and cookieParser().

c) Write a request timer. Write a custom middleware requestTimer that stores the current time on req.startTime (using Date.now()), and calls next(). Register it after the standard stack above.

d) Write an API key guard. Write a custom middleware requireApiKey, checking req.get('X-API-Key') against a fixed value, returning 401 with a JSON error if it doesn’t match, calling next() if it does.

e) Build two routes. GET /public, open to everyone, responding with a JSON message and elapsedMs: Date.now() - req.startTime (using the timer from step c). GET /private, protected by requireApiKey, responding with a JSON success message only when the correct key is provided.

bash
curl http://localhost:4212/public
text
{"message":"public route","elapsedMs":1}
bash
curl -w " [%{http_code}]" http://localhost:4212/private
text
{"error":"Invalid or missing API key"} [401]
bash
curl -w " [%{http_code}]" -H "X-API-Key: letmein" http://localhost:4212/private
text
{"message":"private route accessed"} [200]

f) Verify every piece is active. Using curl -i, confirm: Morgan logs both requests server-side, Helmet’s security headers appear on responses, CORS headers appear when an Origin header is sent, and elapsedMs on /public is a small positive number, confirming the request timer ran before the route handler.

g) Break it, then fix it. Temporarily reorder requireApiKey to run before express.json() on a route that also reads req.body, if that route depended on req.body being parsed, would it break? Test your prediction, then restore the correct order.

Recap

This module covered Express’s middleware pattern from every angle: what middleware is and why next() matters, built-in middleware (express.json, express.urlencoded), writing custom middleware (both app-wide and route-specific), and the standard third-party stack, Morgan for logging, Helmet for security headers, CORS for cross-origin requests, cookie-parser for reading cookies, and compression for smaller responses.

Next module: error handling, what happens when something inside a route or middleware goes wrong.