Routing
Matching method + path to handlers. Radix trees, parameters, versioning.
What Routing Is
Routing is the process of matching an incoming HTTP request to the correct handler function. It's based on two things: the HTTP method and the URL path.
GET /users → list all users
GET /users/:id → get one user
POST /users → create a user
PUT /users/:id → update a user
DELETE /users/:id → delete a user
A router is fundamentally a lookup table: given (method, path), return the handler.
Route Parameters vs Query Strings
Route parameters (:id) are part of the path — they identify a specific resource:
GET /users/42 → id = 42
GET /posts/abc-slug → slug = "abc-slug"
Query strings (?key=value) are optional and used for filtering, sorting, pagination:
GET /users?role=admin&page=2&limit=20
GET /products?sort=price&order=asc
Rule of thumb:
• Use route params for resource identity (what resource?)
• Use query strings for modifying the request (how to return it?)
Route Matching Algorithms
Routers must handle:
Static routes — /health, /users (exact match, fastest)
Parameterized — /users/:id (one segment wildcard)
Wildcard — /files/* (matches anything after)
Regex routes — /users/:id(\d+) (only numeric IDs)
Most production routers use a radix tree (prefix tree) for O(log n) matching instead of linear scan. When you register 1000 routes, each request still resolves almost instantly.
Order matters: routers match routes in registration order or by specificity. /users/settings must be registered BEFORE /users/:id or "settings" gets swallowed as a param.
Nested & Grouped Routes
In production APIs, routes are organized into groups sharing a prefix and middleware:
/api/v1/
auth/
POST /login
POST /logout
POST /refresh
users/ ← requires auth middleware
GET /
GET /:id
PUT /:id
admin/ ← requires auth + admin middleware
GET /users
DELETE /users/:id
This grouping keeps code organized and applies shared middleware efficiently. Never put all routes in one flat file — that's a maintenance nightmare.
API Versioning
APIs evolve, but existing clients can't break. Versioning strategies:
1. URL versioning (most common): /api/v1/users, /api/v2/users
Pros: Explicit, cacheable, easy to route. Cons: URL pollution.
2. Header versioning: Accept: application/vnd.myapi.v2+json
Pros: Clean URLs. Cons: Hidden, hard to test in browser.
3. Query param: /users?version=2
Rarely recommended — pollutes queries.
Best practice: URL versioning with v1/v2 prefix. Maintain old versions until clients migrate. Deprecate with a sunset header and clear timeline.
The Backend from First Principles series is based on what I learnt from Sriniously's YouTube playlist — a thoughtful, framework-agnostic walk through backend engineering. If this material helped you, please go check the original out: youtube.com/@Sriniously. The notes here are my own restatement for revisiting later.