What is routing in Express?
Routing is a fundamental concept in web application development, and Express.js provides a robust and flexible system for defining routes. In Express, routing refers to how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, etc.). Each route can have one or more handler functions that are executed when the route is matched.
What is Routing?
At its core, routing is the process of defining how an application's server will respond to different client requests. When a user navigates to a specific URL (like '/users' or '/products/123'), the server needs to know what code to execute to handle that request. This mapping of a URL and HTTP method to a specific action is what routing accomplishes.
How Express Handles Routing
Express applications use route methods to define routes. These methods are derived from HTTP methods (GET, POST, PUT, DELETE, etc.) and are attached to an instance of the express application. The basic structure for defining a route is app.METHOD(PATH, HANDLER), where:
appis an instance ofexpress.METHODis an HTTP request method (e.g.,get,post,put,delete). There's alsoapp.all()for all methods.PATHis a string, a string pattern, or a regular expression representing the route's path.HANDLERis a callback function or an array of callback functions that Express invokes when it matches the route and HTTP method.
Route Methods
Express provides methods for all standard HTTP verbs. This allows you to differentiate actions based on the type of request.
const express = require('express');
const app = express();
// GET request to the homepage
app.get('/', (req, res) => {
res.send('Welcome to the homepage!');
});
// POST request to /users
app.post('/users', (req, res) => {
res.send('Create a new user');
});
// PUT request to /products/:id
app.put('/products/:id', (req, res) => {
res.send(`Update product ${req.params.id}`);
});
// DELETE request to /items/:id
app.delete('/items/:id', (req, res) => {
res.send(`Delete item ${req.params.id}`);
});
// Route for all HTTP methods
app.all('/secret', (req, res, next) => {
console.log('Accessing the secret section...');
next(); // pass control to the next handler
});
app.get('/secret', (req, res) => {
res.send('This is a secret GET route!');
});
Route Paths
Route paths can be simple strings, string patterns with wildcards, or regular expressions. This flexibility allows for matching various URL structures.
// Matches requests to /about
app.get('/about', (req, res) => {
res.send('About page');
});
// Matches requests to /random.text
app.get('/random.text', (req, res) => {
res.send('random.text');
});
// Matches anything with 'a' in it (e.g., /abcd, /a, /a_b)
app.get(/a/, (req, res) => {
res.send('URL contains "a"');
});
// Matches 'flights' followed by a number (e.g., /flights/123)
app.get('/flights/:id', (req, res) => {
res.send(`Flight ID: ${req.params.id}`);
});
// Matches 'users' followed by anything (e.g., /users/profile, /users/settings)
app.get('/users/*', (req, res) => {
res.send('User route with wildcard');
});
Route Handlers
Route handlers are callback functions that receive request (req) and response (res) objects as arguments. They can also take a next function for middleware. Handlers are responsible for processing the request and sending a response back to the client.
app.get('/example', (req, res) => {
// Access request data (query parameters, body, headers)
console.log(req.query);
// Send a response
res.status(200).json({
message: 'Data received',
method: req.method
});
});
Advanced Routing Concepts
Route Parameters
Route parameters are named URL segments used to capture values specified at their position in the URL. The captured values are stored in the req.params object, with the name of the parameter as the key.
// URL: /users/john/books/programming
app.get('/users/:userId/books/:bookId', (req, res) => {
res.send(`User ID: ${req.params.userId}, Book ID: ${req.params.bookId}`);
});
Route Handlers with Multiple Callbacks (Middleware)
You can provide multiple callback functions that behave like middleware to handle a request. These functions can be an array or simply multiple arguments passed to the route method. The next() function is used to pass control to the next handler in the chain.
const logger = (req, res, next) => {
console.log(`Request received at: ${new Date().toISOString()}`);
next(); // Pass control to the next handler
};
const authChecker = (req, res, next) => {
// Imagine some authentication logic here
const isAuthenticated = true; // Placeholder
if (isAuthenticated) {
next();
} else {
res.status(401).send('Unauthorized');
}
};
// Using multiple arguments for handlers
app.get('/dashboard', logger, authChecker, (req, res) => {
res.send('Welcome to your dashboard!');
});
// Using an array of handlers
const handlers = [logger, authChecker, (req, res) => {
res.send('Another way to dashboard!');
}];
app.get('/another-dashboard', handlers);
express.Router
For larger applications, organizing routes can become complex. Express provides express.Router to create modular, mountable route handlers. A Router instance acts like a mini-application, capable of defining its own middleware and routes, which can then be 'mounted' on a specific path in the main application.
const express = require('express');
const app = express();
const userRouter = express.Router();
// Middleware specific to the userRouter
userRouter.use((req, res, next) => {
console.log('User router specific middleware ran');
next();
});
// Define routes on the userRouter
userRouter.get('/', (req, res) => {
res.send('List of users');
});
userRouter.get('/:id', (req, res) => {
res.send(`Details for user ${req.params.id}`);
});
// Mount the userRouter on the /api/users path
app.use('/api/users', userRouter);
// Now, GET /api/users will hit userRouter.get('/')
// And GET /api/users/123 will hit userRouter.get('/:id')
Summary
Routing in Express.js is the mechanism for mapping client requests (based on URL path and HTTP method) to server-side handler functions. It allows developers to build structured, RESTful APIs and web applications by clearly defining how different endpoints are processed. With features like route parameters, middleware integration, and modular routers, Express provides a powerful and flexible framework for handling complex routing requirements.