Sikau

Project: An orders API · Day 2 · about 40 min

Express: middleware and errors

A request-id middleware, validated pagination and a central error handler.

Let the framework route

Express gives you routing, params, query parsing and JSON for free. Its real power is middleware: small functions every request flows through — for request ids, auth, logging — and one error handler at the end so a failure never leaks a stack trace.

app.js

import express from "express";
import { MENU } from "./lib/menu.js";
import { loadSpecials } from "./lib/specials.js";

const app = express();

let nextId = 1;
app.use((req, res, next) => {
  res.set("X-Request-Id", String(nextId++));
  next();
});

app.get("/api/dishes", (req, res) => {
  const page = Number(req.query.page ?? 1);
  const limit = Number(req.query.limit ?? 10);
  if (!Number.isInteger(page) || page < 1 || !Number.isInteger(limit) || limit < 1) {
    return res.status(400).json({ error: "Invalid page" });
  }
  const all = req.query.veg === "true" ? MENU.filter((d) => d.veg) : MENU;
  const items = all.slice((page - 1) * limit, page * limit);
  res.json({ items, page, total: all.length });
});

app.get("/api/dishes/:id", (req, res) => {
  const dish = MENU.find((d) => d.id === Number(req.params.id));
  if (!dish) return res.status(404).json({ error: "Dish not found" });
  res.json(dish);
});

app.get("/api/specials", async (req, res, next) => {
  try {
    res.json(await loadSpecials());
  } catch (err) {
    next(err);
  }
});

app.use((err, req, res, next) => {
  console.error(err.message);
  res.status(500).json({ error: "Something went wrong" });
});

export default app;

The rest of this lesson

  • Pagination done safelyexplain
  • Async errors in Expressexplain
  • Which page?predict
  • Which items?predict
  • Write app.jswrite code
  • Badge quizquiz
  • What you builtrecap

Continue this lesson free — run real code in your browser

Continue with Google

See all 5 lessons of Project: An orders API