Lessons in this course (11)

6. Express.js — routing, middleware and error handling

Basic★ Must knowLesson 6 of 11
js
import express from 'express';
import helmet from 'helmet';
import cors from 'cors';

const app = express();
app.use(helmet());                                    // security headers
app.use(cors({ origin: ['http://localhost:4200'] }));
app.use(express.json({ limit: '1mb' }));               // parse JSON bodies

app.use((req, res, next) => {                          // custom middleware (logging)
  const start = Date.now();
  res.on('finish', () => console.log(`${req.method} ${req.originalUrl} ${res.statusCode} ${Date.now() - start}ms`));
  next();
});

app.get('/api/products', async (req, res) => {
  const page = Number(req.query.page ?? 1);
  res.json(await productService.list(page));
});
app.get('/api/products/:id', async (req, res) => {
  const p = await productService.get(Number(req.params.id));
  if (!p) return res.status(404).json({ title: 'Not found' });
  res.json(p);
});
app.post('/api/products', async (req, res) => {
  const created = await productService.create(req.body);
  res.status(201).location(`/api/products/${created.id}`).json(created);
});

app.use((req, res) => res.status(404).json({ title: 'Route not found' }));   // 404 handler
app.use((err, req, res, next) => {                                           // error handler: 4 parameters
  console.error(err);
  res.status(err.status ?? 500).json({ title: err.status ? err.message : 'Unexpected error' });
});

app.listen(3000);
  • Middleware runs in registration order; each calls next() or ends the response.
  • Express 5 (stable 2024) forwards rejected promises from async handlers to the error middleware automatically (Express 4 needed try/catch or express-async-errors).
  • Validate input (zod/Joi/express-validator) — never trust req.body.