Router
Comprehensive guide to using Express Router for modular route handling in Node.js applications, including detailed examples, route parameters, middleware usage, and best practices.
Express Router: Organizing Your Routes
In Express.js, the Router is a built-in mechanism that helps you organize your application’s route handling by creating modular, mountable route handlers.
Without the router, all your routes would live in a monolithic app.js or index.js, which quickly becomes unmanageable as your application grows.
Why Use Express Router?
- Modularity: Split your application into separate route files based on functionality.
- Reusability: Reuse route modules across applications.
- Maintainability: Easier to manage and navigate large codebases.
- Middleware Isolation: Apply middleware only to specific routes.
Basic Usage Example
Step 1: Create a Simple Express App
const express = require('express');
const app = express();
app.use(express.json());
app.get('/', (req, res) => {
res.send('Welcome to the main API!');
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});Step 2: Using Express Router
Define Routes in a Separate File (userRoutes.js):
const express = require('express');
const router = express.Router();
// Sample users data
const users = [
{ id: 1, name: 'Harsha' },
{ id: 2, name: 'Alex' }
];
// Route: Get all users
router.get('/', (req, res) => {
res.json(users);
});
// Route: Get user by ID
router.get('/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (user) {
res.json(user);
} else {
res.status(404).json({ error: 'User not found' });
}
});
// Export the router
module.exports = router;Integrate Router into Main App (app.js):
const express = require('express');
const userRoutes = require('./userRoutes');
const app = express();
app.use(express.json());
// Mount the user routes at /users
app.use('/users', userRoutes);
app.listen(3000, () => {
console.log('Server running on port 3000');
});Now, visiting /users will return all users, and /users/1 will return the user with id = 1.
Route Parameters and Query Parameters
Route Parameters Example
router.get('/profile/:username', (req, res) => {
const username = req.params.username;
res.send(`Profile page of ${username}`);
});Request: GET /profile/harsha → Response: "Profile page of harsha"
Query Parameters Example
router.get('/search', (req, res) => {
const query = req.query.q;
res.send(`Search results for: ${query}`);
});Request: GET /search?q=express → Response: "Search results for: express"
Applying Middleware to Router
Middleware functions are functions that have access to the request object, response object, and next middleware function in the application’s request-response cycle.
Example: Logging Middleware
const logger = (req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
};
router.use(logger);This will log every request to the router endpoints.
Advanced Usage: Router-Level Middleware
// Protect routes with authentication middleware
function authMiddleware(req, res, next) {
const token = req.headers['authorization'];
if (token === 'valid-token') {
next();
} else {
res.status(401).json({ error: 'Unauthorized' });
}
}
// Apply to all /users routes
router.use(authMiddleware);Combining Multiple Routers
You can have multiple routers for different parts of your API.
Example Directory Structure:
/routes
- userRoutes.js
- productRoutes.js
app.jsMount multiple routers:
app.use('/users', require('./routes/userRoutes'));
app.use('/products', require('./routes/productRoutes'));Error Handling in Routes
You can define error-handling middleware in your router.
router.get('/error', (req, res, next) => {
const err = new Error('Something went wrong');
next(err);
});
// Error handling middleware
router.use((err, req, res, next) => {
res.status(500).json({ error: err.message });
});Best Practices
- Keep each router focused on a single resource (e.g., User, Product).
- Apply route-specific middleware in the router itself, not globally.
- Always handle errors gracefully.
- Use validation middleware (e.g., Zod) to validate inputs at the router level.
- Mount routers in a hierarchical manner to create a clean URL structure.