Module Recap
Module 04 covered middleware and project structure — the patterns that turn a simple Express script into a maintainable, production-quality API.
What you learned
Section titled “What you learned”Middleware is the (req, res, next) pipeline. Every request passes through a chain of functions before reaching a route handler. Each function can modify req/res, end the request, or call next() to continue. Order matters.
Built-in and third-party middleware handle common needs. express.json() parses request bodies. cors() enables cross-origin requests from your frontend. morgan() logs every request. Register them before routes, in this order.
Custom middleware is just functions. Write middleware factories (functions that return middleware) for reusable, configurable behavior. Use res.locals to attach request-scoped data for downstream handlers.
Express Router groups related routes. express.Router() creates a sub-application mounted at a path. Separate route files by resource. Separate business logic into controller files — route files only map paths to controller functions.
Error middleware centralizes error handling. The 4-argument (err, req, res, next) signature identifies error middleware. A custom AppError class carries status codes. Register error middleware last. Wrap async handlers to catch Promise rejections.
How this connects to Bulletin
Section titled “How this connects to Bulletin”The Bulletin API’s structure after Module 04:
// src/index.ts — clean, declarativeimport express from 'express'import cors from 'cors'import morgan from 'morgan'import authRouter from './routes/auth.js'import postsRouter from './routes/posts.js'import commentsRouter from './routes/comments.js'import { errorHandler } from './middleware/errorHandler.js'import { config } from './config.js'
const app = express()
app.use(morgan('dev'))app.use(cors({ origin: config.frontendUrl }))app.use(express.json())
app.use('/auth', authRouter)app.use('/posts', postsRouter)app.use('/posts', commentsRouter)
app.use((req, res) => res.status(404).json({ error: 'Not found' }))app.use(errorHandler)
app.listen(config.port)Every route, middleware, and error handler has a clear, single responsibility.
Key terms
Section titled “Key terms”| Term | What it means |
|---|---|
| Middleware | (req, res, next) function in the Express request pipeline |
next() | Passes to the next middleware; next(err) jumps to error handler |
res.locals | Request-scoped data passed between middleware |
express.json() | Parses JSON bodies into req.body |
cors() | Sets headers to allow cross-origin requests |
morgan() | HTTP request logger |
express.Router() | Creates a sub-application for route grouping |
| Controller | File containing business logic separated from route definitions |
| Error middleware | 4-argument (err, req, res, next) — must be registered last |
AppError | Custom error class that carries an HTTP status code |
What is next
Section titled “What is next”Module 05 — SQLite and Data Persistence →
Module 05 replaces the in-memory data store with a real database. You’ll learn relational database concepts, set up SQLite with better-sqlite3, design the Bulletin schema, and write SELECT, INSERT, UPDATE, and DELETE queries. By the end, your API data survives server restarts.