Express Routers & Route Organization
An Express Router is a mini-application of grouped routes that you mount under a shared URL prefix, letting you split a growing API into small, focused files.
Learn Express Routers & Route Organization in our free Node.js course — a beginner-friendly interactive lesson with worked examples, a practice exercise and…
Part of the free Node.js course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll create routers with express.Router() , mount them with app.use('/api', router) , read route params, chain methods with app.route() , split routes into files, and understand why route order matters.
What You'll Learn in This Lesson
1️⃣ Creating & Mounting a Router
Putting every route directly on app gets messy fast. express.Router() creates a mini-app : a self-contained group of routes you define with relative paths. You then mount it with app.use('/api/users', router) , and every route inside it gains that prefix.
Route parameters — the :id in a path — arrive on req.params . Note they're always strings , so convert with Number() when you need a number.
2️⃣ Chaining Methods with app.route()
When several HTTP methods share the same path — say GET , PUT , and DELETE on /books/:id — repeating that string on every line is noisy. app.route(path) lets you declare the path once and chain the method handlers off it.
3️⃣ Route Order & Splitting Into Files
Express checks routes in the order you declare them and stops at the first match. That means a literal path like /users/me must come before a parameter path like /users/:id — otherwise :id matches first with id = "me" and your specific handler never runs.
In real projects you put each feature's router in its own file and mount them all in app.js . Here's the standard structure (shown as code — it spans multiple files, so it isn't run on one page):
Your turn. Fill in the two blanks marked ___ to create and mount a router, then run it and compare with the expected output.
No blanks this time — build the router yourself from the brief. Add a list route, a by-id route with a 404 fallback, and mount it at /api/products . Run it and check your output against the example in the comments.
📋 Quick Reference — Express Routing
Practice quiz
What is an express.Router()?
- A database table
- A self-contained mini-app of routes you can mount under a prefix
- A middleware that parses JSON
- A logging tool
Answer: A self-contained mini-app of routes you can mount under a prefix. A Router groups related routes into a mountable mini-app with relative paths.
How do you mount a router so its routes live under /api/users?
- app.get('/api/users', router)
- app.mount('/api/users', router)
- router.use('/api/users', app)
- app.use('/api/users', router)
Answer: app.use('/api/users', router). app.use('/api/users', router) mounts the router; each inner route gains that prefix.
Inside a router mounted at /api/users, what path do you write for the by-id route?
- '/:id' (relative to the mount point)
- '/api/users/:id'
- '/users/:id'
- 'api/users/:id'
Answer: '/:id' (relative to the mount point). Router paths are relative to the mount point, so you write '/:id', not the full path.
Why does /users/:id declared before /users/me break the /users/me route?
- Parameter routes are disabled
- Express sorts routes alphabetically
- The :id route matches first with id = 'me', so /users/me never runs
- Routers cannot have literal paths
Answer: The :id route matches first with id = 'me', so /users/me never runs. Express stops at the first match, so the earlier :id route swallows 'me' as the id.
What does app.route('/books/:id') let you do?
- Mount another app
- Parse the request body
- Declare the path once and chain .get(), .delete(), etc.
- Redirect to a new URL
Answer: Declare the path once and chain .get(), .delete(), etc.. app.route(path) declares the path once and chains multiple method handlers off it.
Values in req.params arrive as what type?
- Numbers
- Strings
- Booleans
- Objects
Answer: Strings. Route params are always strings; convert with Number() when you need a number.
Which middleware must you add so req.body is populated on a JSON POST?
- express.static()
- express.urlencoded() only
- app.use(express.json())
- express.router()
Answer: app.use(express.json()). express.json() parses a JSON request body into req.body; without it req.body is undefined.
Your router's routes all return 404. What is the most likely cause?
- You forgot to mount it with app.use(prefix, router)
- You used app.route()
- The port is wrong
- You forgot express.json()
Answer: You forgot to mount it with app.use(prefix, router). Defining a router doesn't connect it; you must mount it with app.use before its routes respond.
What does a double prefix like /api/users/api/users usually mean?
- The port is duplicated
- express.json() is missing
- Two routers share a prefix
- You wrote the full path inside the mounted router instead of a relative one
Answer: You wrote the full path inside the mounted router instead of a relative one. Inside a mounted router use relative paths like '/' and '/:id', not the full prefixed path.
What is the recommended structure for a non-trivial Express API?
- One Router per feature, each in its own file, mounted in app.js
- All routes in a single giant function
- One file per route handler with no routers
- Define routes inside app.listen()
Answer: One Router per feature, each in its own file, mounted in app.js. Create one Router per feature in a routes/ folder and mount them all in app.js.