# Routing (Backend Frameworks)

## 1. What "Routing" Means at the Backend Layer

Routing is the mechanism that maps an incoming request's method + path to the specific function that should handle it. `01-express_fundamentals/` and `02-nestjs_fundamentals/` each showed one concrete implementation of this (imperative `app.get()` calls vs. decorator metadata read at bootstrap) — this topic zooms out to the routing *mechanics themselves*, independent of any one framework's syntax: how patterns are matched, how specificity/ordering is resolved, and how routes are organized at scale.

## 2. Static, Parameterized, and Wildcard Segments

```
/health                    -- static: matches exactly one literal path
/users/:id                 -- parameterized: :id matches any single segment, captured as a value
/files/*                   -- wildcard: * matches one-or-more remaining segments, captured as one string
/users/:id/orders/:orderId -- multiple params in one pattern
```

A router's matching engine walks a request path segment-by-segment against each registered pattern's segments: a static segment must match the literal text exactly, a parameterized segment (`:name`) matches any single segment and captures its value, and a wildcard consumes everything remaining. This is exactly the logic the Express exercises in `01-express_fundamentals/` implement by hand as `matchRoute` — real routers (Express's, NestJS's underlying Express/Fastify, Next.js's file-based router) all do a more optimized version of this same fundamental segment-matching idea.

## 3. Specificity and Ordering

```
GET /users/me      <- registered FIRST
GET /users/:id      <- registered SECOND
```

When two patterns could both match the same incoming path (`/users/me` matches the literal pattern AND the `:id` pattern, since `"me"` is a valid value for `:id`), most routers resolve the ambiguity by **registration order**: whichever pattern was declared first wins, checked in the order routes were added. This is why route-ordering discipline (most specific / most literal first) is a real, load-bearing convention, not a stylistic preference — get it backwards and the more specific route silently never runs, exactly as covered in `01-express_fundamentals/` Common Pitfall 1.

Some routers (Next.js's file-based router among them) instead resolve ambiguity by an explicit **specificity ranking** baked into the routing algorithm itself — a static segment always outranks a dynamic segment at the same position, regardless of file/declaration order — which removes the "order matters" footgun entirely, at the cost of the ranking rules themselves needing to be learned.

![Routes form a tree of segments where static beats parameter beats wildcard, except in Express which matches in registration order](diagrams/01-route-specificity.svg)

## 4. Route Grouping and Prefixing

```ts
// Express: a whole sub-router mounted under one prefix
const usersRouter = express.Router();
usersRouter.get("/", listUsers);       // becomes GET /api/v1/users
usersRouter.get("/:id", getUser);      // becomes GET /api/v1/users/:id
app.use("/api/v1/users", usersRouter);

// NestJS: @Controller("users") on a class mounted inside a module that's
// itself imported under a global prefix (app.setGlobalPrefix("api/v1"))
```

Grouping related routes under a shared prefix (an API version, a resource name, an admin-only section) keeps route declarations organized as the number of endpoints grows, and centralizes prefix changes (e.g. bumping an API version) to one place instead of editing every individual route string.

## 5. Contrast with Frontend Routing

Both this topic and `frontend/ecosystem/06-react_router/` (and Next.js's own page router) solve a "match a path to a handler" problem, but the handler on each side does a fundamentally different job: a **backend** route handler processes a request and returns data or a status — no rendering is implied. A **frontend** route handler decides which UI component tree to render for a given URL, entirely client-side (React Router) or via server-rendering (Next.js pages). The matching mechanics (static/parameterized/wildcard segments, specificity resolution) are conceptually the same problem in both places — it's the *handler's job* on the other end that differs.

## Common Pitfalls

1. **Registering a general pattern before a more specific literal one**, in a router that resolves ambiguity by registration order — the specific route silently never runs (section 3).
2. **Deeply nested manual route strings repeated across files** instead of grouping related routes under one mounted prefix — makes a prefix change (like an API version bump) require hunting down every individual route string.
3. **Assuming wildcard and parameterized segments behave the same way.** A wildcard (`*`) swallows multiple remaining segments as one value; a parameterized segment (`:id`) matches exactly one segment — mixing them up produces routes that either over-match or under-match.
4. **Forgetting that route matching is case-sensitive and trailing-slash-sensitive by default in most routers** — `/Users` and `/users`, or `/users` and `/users/`, are not automatically treated as the same route unless the router is explicitly configured to normalize them.

## Quick Reference

```
/health              -- static segment, exact literal match
/users/:id            -- parameterized segment, matches one segment, captured
/files/*               -- wildcard, matches one-or-more remaining segments

Ambiguity resolution:
  registration-order routers (Express, NestJS's underlying router) -- first match wins
  ranking-based routers (Next.js file router) -- static always outranks dynamic, order-independent

Group related routes under one mounted prefix -- centralizes prefix changes (versioning, resource grouping)
Backend routing -> returns data/status | Frontend routing -> decides which UI to render
```
