Well-structured backends separate concerns: routers define URLs, controllers translate HTTP to application calls, services own data access, and middleware handles cross-cutting behavior (validation, 404, errors). Study these patterns to keep files small, testable, and aligned with REST conventions.

How routers and controllers work together — Intermediate

The router owns URLs and HTTP verbs; the controller owns request/response logic. The router should only import the controller and connect paths—never contain SQL or heavy logic.
Learn: In the course architecture, the router answers WHERE and HOW (path + HTTP verb) while the controller answers WHAT HAPPENS for that request (read req.params, req.query, req.body, set status, send JSON). The router imports the controller object and passes function references—controller.list not controller.list()—so Express invokes them when a match occurs. Validation middleware, if any, is chained on the router before the controller. Services sit behind the controller for Knex/SQL. This split is what Organizing Express demonstrates with pastes and users modules.

Supplementary examples

Mount router on app (app.js)

const usersRouter = require("./users/users.router");
const pastesRouter = require("./pastes/pastes.router");

app.use("/users", usersRouter);
app.use("/users/:userId/pastes", pastesRouter);

Controller exports named handlers

// pastes.controller.js
module.exports = {
  list,
  create,
  read,
  update,
  remove,
};

Router chains validation then controller

const validateCreate = require("./pastes.validators");
router.post("/", validateCreate, controller.create);

methodNotAllowed for unsupported verbs

router
  .route("/:pasteId")
  .get(controller.read)
  .put(controller.update)
  .delete(controller.remove)
  .all(methodNotAllowed);

Course example

// pastes.router.js — wiring only (no business logic here)
const router = require("express").Router({ mergeParams: true });
const controller = require("./pastes.controller");
const methodNotAllowed = require("../errors/methodNotAllowed");

router
  .route("/")
  .get(controller.list)
  .post(controller.create)
  .all(methodNotAllowed);

router
  .route("/:pasteId")
  .get(controller.read)
  .put(controller.update)
  .delete(controller.remove)
  .all(methodNotAllowed);

module.exports = router;

Additional references & examples

← All Organizing Express code · Server Architecture / Routes