Routing is a fundamental concept in web development, allowing you to define how different URLs map to specific functions or handlers in your application. In Node.js, routing can be achieved using various frameworks and libraries, but the most popular choice is Express.js. This tutorial will guide you through setting up routing in a Node.js application using Express.js.
Before we dive into routing, ensure that you have Node.js installed on your machine. You can download it from nodejs.org. Once Node.js is installed, create a new directory for your project and initialize it with npm:
mkdir node-routing-tutorial
cd node-routing-tutorial
npm init -y
Next, install Express.js by running the following command:
npm install express
Express.js provides a simple way to define routes using the app.METHOD(path, handler) syntax, where METHOD is an HTTP method (e.g., get, post, put, delete), path is the URL path, and handler is the function that will be executed when the route is matched.
Create a file named app.js in your project directory and add the following code:
const express = require('express');
const app = express();
const PORT = 3000;
// Define a basic GET route
app.get('/', (req, res) => {
res.send('Hello, World!');
});
// Start the server
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
This code sets up an Express application with a single GET route that responds with "Hello, World!" when accessed.
To handle POST requests, you can define another route like this:
// Define a basic POST route
app.post('/submit', (req, res) => {
res.send('Data received!');
});
Express.js allows you to define dynamic routes using route parameters. These parameters are captured from the URL and passed to your handler function.
// Define a dynamic route with parameters
app.get('/user/:id', (req, res) => {
const userId = req.params.id;
res.send(`User ID: ${userId}`);
});
In this example, :id is a route parameter that captures any value in the URL path after /user/. The captured value is accessible through req.params.id.
Route handlers can be defined as separate functions for better code organization and reusability.
// Define a separate route handler function
function getUser(req, res) {
const userId = req.params.id;
res.send(`User ID: ${userId}`);
}
// Use the route handler in the route definition
app.get('/user/:id', getUser);
You can also define multiple handlers for a single route. Each handler function is executed sequentially, and you can pass control to the next handler using next().
// Define multiple route handlers
function logRequest(req, res, next) {
console.log(`Received request for ${req.url}`);
next(); // Pass control to the next handler
}
function handleUser(req, res) {
const userId = req.params.id;
res.send(`User ID: ${userId}`);
}
// Use multiple handlers in the route definition
app.get('/user/:id', logRequest, handleUser);
Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. These functions can execute any code, make changes to the request and the response objects, end the request-response cycle, and call the next middleware function.
// Define a simple middleware function
function checkUser(req, res, next) {
if (req.params.id === 'admin') {
return res.send('Admin access granted!');
}
next(); // Pass control to the next handler
}
// Use the middleware in the route definition
app.get('/user/:id', checkUser, handleUser);
In this example, checkUser is a middleware function that checks if the user ID is 'admin'. If it is, it sends a response and ends the request cycle. Otherwise, it passes control to the next handler.
For larger applications, you might want to organize your routes into groups or modules. Express.js supports this through route files and express.Router().
Create a new directory named routes and add a file named users.js:
// routes/users.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.send('List of users');
});
router.get('/:id', (req, res) => {
const userId = req.params.id;
res.send(`User ID: ${userId}`);
});
module.exports = router;
Then, in your app.js file, import and use this router:
const express = require('express');
const app = express();
const PORT = 3000;
// Import the users router
const usersRouter = require('./routes/users');
// Use the users router for all routes starting with /users
app.use('/users', usersRouter);
// Start the server
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
Express.js provides a way to handle errors using middleware functions. These middleware functions are defined after all other routes and handlers.
// Define an error handling middleware function
function errorHandler(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
}
// Use the error handler in the application
app.use(errorHandler);
In this example, errorHandler is a middleware function that logs the error stack and sends a 500 status response with a message.
express.Router().Routing is a crucial aspect of web development in Node.js, allowing you to define how different URLs map to specific functions or handlers. By using Express.js, you can easily set up routing with dynamic routes, multiple handlers, and middleware functions. Organizing your routes into separate files and using best practices will help you build maintainable and scalable applications.
This tutorial has covered the basics of routing in Node.js using Express.js. You should now be able to define routes, handle different HTTP methods, use route parameters, organize your routes, and implement error handling. Happy coding!