Skip to content

ExpressJS - Routing

Routing is the process of determining how an application responds to a client request for a specific endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, etc.).

The basic structure of a route in Express is:

app.METHOD(PATH, HANDLER)
  • app is an instance of Express.
  • METHOD is an HTTP request method in lowercase (e.g., get, post).
  • PATH is the path on the server.
  • HANDLER is the function executed when the route is matched.
import express from 'express';
const app = express();
// Responds to GET requests at the root URL
app.get('/', (req, res) => {
res.send('Welcome to the homepage!');
});
// Responds to POST requests at '/api/users'
app.post('/api/users', (req, res) => {
res.send('New user created!');
});
app.listen(3000);

Route parameters are named URL segments used to capture values at specific positions in the URL. The captured values are populated in the req.params object.

// Route path: /users/:userId/books/:bookId
// Request URL: http://localhost:3000/users/101/books/42
// req.params will be: { "userId": "101", "bookId": "42" }
app.get('/users/:userId/books/:bookId', (req, res) => {
const { userId, bookId } = req.params;
res.send(`Fetching book with ID ${bookId} for user with ID ${userId}.`);
});

As your application grows, defining all routes in a single file becomes unmanageable. express.Router is a mini-Express application that allows you to group route handlers and middleware, keeping your code modular and organized.

A common practice is to separate routes into their own files within a routes directory.

my-app/
├── src/
│ ├── routes/
│ │ ├── users.routes.js
│ │ └── products.routes.js
│ └── app.js # Main app file
└── package.json

First, define the user-related routes in src/routes/users.routes.js.

src/routes/users.routes.js
import express from 'express';
const router = express.Router();
// Note: The path here is relative to the path defined in app.js
// GET /api/users/
router.get('/', (req, res) => {
res.json({ message: 'List of all users' });
});
// POST /api/users/
router.post('/', (req, res) => {
res.status(201).json({ message: 'User created' });
});
// GET /api/users/:id
router.get('/:id', (req, res) => {
res.json({ message: `Details for user ${req.params.id}` });
});
// Important: Export the router
export default router;

Next, import and use this router in your main application file, src/app.js.

src/app.js
import express from 'express';
import usersRouter from './routes/users.routes.js';
// import productsRouter from './routes/products.routes.js'; // You would add other routers here
const app = express();
const PORT = 3000;
app.use(express.json()); // Middleware for parsing JSON
// Mount the routers
// All routes in usersRouter will be prefixed with '/api/users'
app.use('/api/users', usersRouter);
// app.use('/api/products', productsRouter);
app.get('/', (req, res) => {
res.send('API is running...');
});
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});
  • Modularity: Keeps related routes together, making the code easier to understand and find.
  • Maintainability: Changes to user-related endpoints only require modifying the users.routes.js file.
  • Reusability: You can apply middleware specifically to one router, which will then apply to all routes defined within it.

By using express.Router, you create a clean, scalable, and professional structure for your Express applications, which is essential for any project beyond a simple demo.