3.1 · Express: routes, middlewares, requests & responses

Level 3 · Express & databases

3.1Express: routes, middlewares, requests & responses

Goal: build an application/API with Express: routing (including dynamic routes), enriched req/res, and middlewares — the heart of Node web development.
Estimated time: 12 min · self-paced reading · If you only have 5 min: read “The essentials in 30s” + the diagram.

The essentials in 30 seconds

  • Express refines the http module: clean routing (app.get/post/put/delete), dynamic parameters (/users/:id → req.params.id), one-line responses (res.json).
  • Middleware is the key concept: a (req, res, next) function that each request passes through; it acts, then calls next() or responds to stop the chain.
  • Pipeline order matters: parse first (express.json()), then validate and authenticate, respond last with the right status.

Running case — Salim replaces his if cascade with Express

Salim, junior developer in Algiers, serves a mini-catalogue with the native http module: a cascade of ifs on req.url and req.method, a hand-parsed POST body, headers set one by one. He rewrites it all with Express: app.use(express.json()) to parse the body, app.get('/produits/:id') for dynamic pages, a middleware logging each request, res.status(201).json() for creations. Same server, three times more readable code.

This same case returns in the lesson, the diagram, the script and the 48h challenge.

1. Routing & enriched req/res

Express is the reference web framework for Node: minimalist, flexible, built on the http module (section 2-4). Routing maps an HTTP method and a URL to a handler: app.get('/users', handler), app.post('/users', handler), and likewise for put, patch and delete. Dynamic routes capture segments: app.get('/users/:id') makes the identifier readable in req.params.id.

Objects are enriched compared to native. On the request side: req.params (route parameters), req.query (query string after the ?), req.body (parsed body, available thanks to express.json()). On the response side: res.json(data) sends JSON in one method, res.status(201).json(...) sets the status then sends, res.send and res.redirect cover the other cases. Salim gains the essentials: no more manual parsing, readable routes, explicit responses.

2. Middleware: a pipeline where order matters

Middleware is THE key concept of Express: a (req, res, next) function that runs during the processing of a request. It can inspect or modify req and res (attaching req.user after authentication), run code (logging, validating, measuring), then call next() to move to the next middleware — or send a response to stop the chain (for example returning 401 without going further).

Each request passes through a pipeline in declaration order: express.json() parsing the body, your middlewares (log, auth, validation), then the final handler that responds. Everything is middleware: parsing, static files, auth, error handling. Two habits from Salim: parse before validating (otherwise req.body is empty) and always call next() or respond (otherwise the request stays stuck). A middleware applies globally (app.use(...)) or on one specific route.

Common misinterpretation: “Express replaces Node and middleware is optional, next() can be forgotten”. No. Express relies on the http module and only dresses it up; and a middleware calling neither next() nor res.json()/res.send() leaves the request hanging until timeout. The order (parse, then validate, then respond) is part of the contract.
The Express pipeline Each request passes through middlewares in order Request GET/produits/:idexpress.json() Parsethe bodyMiddlewares Log, auth,validation + next()Handler res.json /res.status().json
Each request passes through middlewares in order
Text version of the diagram (SEO / screen readers / translation): 1) Request: Salim receives GET /produits/7 on his server in Algiers. 2) Parsing: express.json() prepares req.body for POSTs. 3) Middlewares: his logger records the request then calls next(), his check validates the data. 4) Handler: the dynamic route reads req.params.id and answers res.json(). Lesson: the parse → validate → respond order makes the API reliable.

The missing link

“I forgot next() and my request went on holiday.”
A sentence to utter only once in front of your terminal

A middleware that does not pass control on blocks everyone.

🔎 Concrete example — A mini catalogue API in a few lines

Salim rewrites his native server with Express.

const express = require('express');
const app = express();
app.use(express.json());
app.use((req, res, next) => { console.log(req.method, req.url); next(); });
app.get('/produits/:id', (req, res) => res.json({ id: req.params.id }));
app.post('/produits', (req, res) => res.status(201).json(req.body));
app.listen(3000);

Reading: the logger calls next(), the dynamic route reads req.params, creation returns 201.

Lesson: automatic parsing removes all the manual code of the native server.

Section vocabulary

Express
Reference minimalist web framework for Node, built on the http module; brings routing, middlewares and enriched req/res.

Simple example: Salim rewrites his catalogue in it in a few readable lines.

What it is not: a Node replacement that would do without the http module.

Reflex: use it for any API or web app rather than raw native.

Routing
Mapping an HTTP method and a URL to a handler: app.get('/users', ...), app.post(...), with dynamic routes '/users/:id'.

Simple example: GET /produits/7 captured by app.get('/produits/:id').

What it is not: a cascade of ifs on req.url in a native server.

Reflex: one route per intention, with the right HTTP verb.

Middleware
A (req, res, next) function run during request processing; acts on req/res then calls next() or sends a response.

Simple example: Salim’s logger recording each request then passing control on.

What it is not: a mere utility function never plugged into the pipeline.

Reflex: always end with next() or with a response.

Middleware pipeline
Ordered chain of middlewares each request passes through: parsing, log, auth, validation, final handler.

Simple example: express.json() then validation then handler at Salim’s.

What it is not: isolated handlers with no order or sharing.

Reflex: parse first, validate next, respond last.

Enriched req / res
Express objects: req.params, req.query, req.body on the request side; res.json, res.status, res.send, res.redirect on the response side.

Simple example: req.params.id read and res.status(201).json() returned.

What it is not: the raw req/res of the http module with no help.

Reflex: read the body in req.body, answer with res.json().

In practice — Build an application with Express

  1. Create an Express app (const app = express()), add app.use(express.json()) to parse JSON, and start it with app.listen(3000).
  2. Define routes: app.get('/users', ...), app.post('/users', ...), and a dynamic route app.get('/users/:id', ...) (read req.params.id).
  3. Return responses with the enriched methods: res.json(data), res.status(201).json(...), and read the body with req.body.
  4. Write your own (req, res, next) middleware logging each request, apply it with app.use(...) and call next().
You build an application/API with Express: routing (including dynamic routes), enriched req/res, and middlewares — the heart of Node web development.

Ready-to-say script — presenting your Express API (30 s)

“I built the catalogue API with Express: express.json to parse the body, a dynamic /produits/:id route read in req.params, a middleware logging then calling next, and res.json responses with the right status, 201 for creations. Tested in the browser on localhost:3000.”

Say in review; show the dynamic route and the log of one request.

Copy-paste template — minimal Express server

const express = require('express');
const app = express();
app.use(express.json());
app.use((req, res, next) => {
  console.log(req.method, req.url);
  next();
});
app.get('/produits/:id', (req, res) => {
  res.json({ id: req.params.id });
});
app.post('/produits', (req, res) => {
  res.status(201).json(req.body);
});
app.listen(3000, () => console.log('OK port 3000'));

Freelancer

A quote API in Express is enough: two GET/POST routes and a log middleware, no heavy framework.

SME in Algiers

Salim exposes the internal catalogue: dynamic routes by product reference, 200/201/404 statuses honoured.

Product team

Standardise the pipeline (json, log, auth, validation) so each route inherits the same foundation.

Beginner

This week: a single server, one dynamic GET route and one middleware calling next().

✓ Best practices

  • Think “pipeline”: everything is middleware, order matters.
  • Use express.json() to parse the body, and res.json() to respond.
  • Encapsulate cross-cutting concerns (auth, log) in reusable middlewares.

✗ Common pitfalls

  • Forgetting to call next() (the request stays stuck).
  • Ordering middlewares badly (validating before parsing).
  • Putting all logic in one handler instead of composing middlewares.

Key takeaways

  • EXPRESS = the reference Node web framework (built on http): simplifies routing, parsing and request handling.
  • ROUTING: app.get/post/put/delete('/path', handler); dynamic routes /users/:id → req.params.id.
  • MIDDLEWARE (req, res, next) is THE key concept: it acts during processing, then next() moves to the next one — a PIPELINE.
  • Everything is middleware: express.json(), static, auth, error handling, your own middlewares (app.use or per route).

48h challenge — apply tomorrow

Set up 1 Express API with 1 dynamic route and 1 log middleware calling next().

Section exit checklist
  • I state the role of next() without hesitating.
  • I read req.params, req.query and req.body.
  • My API answers res.json() with the right status.
Self-rating 1-5: are my middlewares ordered (parsing before validation)?does each middleware call next() or respond?

Frequently asked questions

What exactly is a middleware, and why is it the central concept of Express?

A middleware is a (req, res, next) function that runs during the processing of a request. It can inspect the request, modify req/res (for example attaching req.user), run code (logging, validating), then decide: call next() to move to the next one, or send a response to stop the chain (an auth middleware returning 401). It is central because everything is middleware in Express: parsing (express.json()), static, auth, validation, error handling — and your route handlers are the last link. Thinking “ordered pipeline” rather than “isolated functions” means understanding Express.

Why is Express so popular, and are there alternatives?

Minimalist and unopinionated (routing + middlewares, freedom of structure), easy to start, mature and proven, a huge ecosystem of middlewares and the de facto standard expected of a Node developer. Its limits (choices to make yourself, no imposed structure) motivate alternatives like Fastify, Koa or NestJS on large projects. But to learn then ship fast, Express remains the default choice — the one Salim masters first in Algiers.

Check your understanding

In an Express middleware, what does the (req, res, next) contract require?

Additional resources (optional, to go further)

Level 3 examFresh, harder questions to test what you've learned