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.

Building routes

Matches the lesson Building routes: define paths and HTTP verbs on a router or app.

4 topic(s) on this page.

How to create an Express router — Basic

Instantiate Router(), wire handlers, and export the router for mounting on the app.
Learn: An Express Router is a mini-app: it has its own middleware stack and routes, then mounts on the main app. `mergeParams: true` lets nested routers see parent params (e.g. `:userId` from a parent mount). Always export the router for `app.use`.

Supplementary examples

Router module skeleton

const router = require("express").Router({ mergeParams: true });

// routes here

module.exports = router;

Mount in app.js

const pastesRouter = require("./pastes/pastes.router");
app.use("/pastes", pastesRouter);

Course example

const router = require("express").Router({ mergeParams: true });

Additional references & examples

How to define routes on the app directly — Basic

Attach handlers with app.get/post before splitting logic into router modules.
Learn: Defining routes directly on `app` is fine for tiny projects or quick experiments. As endpoints multiply, inline handlers become hard to test and navigate—splitting into router modules keeps each file responsible for one resource area.

Supplementary examples

GET and POST on the app

app.get("/pastes", (req, res, next) => list(req, res, next));
app.post("/pastes", (req, res, next) => create(req, res, next));

Route parameters on the app

app.get("/users/:userId", (req, res) => {
  const { userId } = req.params;
  res.json({ userId });
});

Course example

// New middleware function to validate the request body
function bodyHasTextProperty(req, res, next) {
const { data: { text } = {} } = req.body;
if (text) {
return next(); // Call `next()` without an error message if the result exists
}
next("A 'text' property is required.");
}
let lastPasteId = pastes.reduce((maxId, paste) => Math.max(maxId, paste.id), 0);
app.post(
"/pastes",
bodyHasTextProperty, // Add validation middleware function
(req, res) => {
// Route handler no longer has validation code.
const { data: { name, syntax, exposure, expiration, text, user_id } = {} } = req.body;
const newPaste = {
id: ++lastPasteId, // Increment last id then assign as the current ID
name,
syntax,
exposure,
expiration,
text,
user_id,
};
pastes.push(newPaste);
res.status(201).json({ data: newPaste });
}
);

Additional references & examples

How to define HTTP routes on a router — Basic

Map GET, POST, PUT, and DELETE handlers to paths using router methods or router.route().
Learn: REST maps actions to HTTP verbs: GET reads, POST creates, PUT/PATCH updates, DELETE removes. Use `router.route(path)` to chain verbs on the same path. Handlers should delegate to controllers, not contain SQL.

Supplementary examples

CRUD routes on one path

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

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

Separate verb methods

router.get("/", controller.list);
router.post("/", controller.create);

Course example

const pastesRouter = require("../pastes/pastes.router");
router.use("/:userId/pastes", pastesRouter);

Additional references & examples

How to mount routers with URL prefixes — Intermediate

Use app.use('/prefix', router) to group related endpoints under a base path.
Learn: Mounting groups related endpoints under a prefix (`/users/:userId/pastes`) keeps URLs readable and mirrors resource ownership. Order matters: register specific routes before catch-all middleware like notFound.

Supplementary examples

Nested resource mount

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

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

Course example

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

Additional references & examples