Routing in Express.js

Deep dive into Express.js routing. Learn how to define routes for different HTTP methods (GET, POST, PUT, DELETE) and how to handle URL parameters.


Mastering Express.js: Routing in Depth

Routing in Express.js: An Overview

Routing, at its core, is the process of determining how an application responds to a client request to a particular endpoint (URI) which is a combination of a specific HTTP method (GET, POST, PUT, DELETE, etc.) and a URL path. In Express.js, routing involves defining handlers for specific URL paths and HTTP methods. When a client makes a request, Express.js examines the request's HTTP method and URL. If a route matching both is found, its associated handler function (often called a middleware function) is executed. This handler is then responsible for processing the request and sending a response back to the client.

Without routing, your Express.js application would essentially be a static server serving only a single default response. Routing allows you to build dynamic and complex web applications that can handle diverse requests and perform various operations based on the requested endpoint.

Deep Dive into Express.js Routing

Defining Routes

In Express.js, routes are defined using the app object, which represents your Express application instance. The `app` object provides methods that correspond to the HTTP methods: app.get(), app.post(), app.put(), app.delete(), app.patch(), and app.all(). Each of these methods takes a path and a callback function as arguments.

The path is a string that represents the URL path for which the route should be matched. The callback function (the route handler) is a function that will be executed when a request matching the specified HTTP method and path is received. This function typically takes two arguments: req (the request object) and res (the response object). You can also use the `next` object to pass control to the next matching route.

Example: Basic Routes

 const express = require('express');
const app = express();
const port = 3000;

// Route for GET requests to the homepage
app.get('/', (req, res) => {
  res.send('Hello World!');
});

// Route for POST requests to create a new resource
app.post('/users', (req, res) => {
  res.send('Received a POST request to create a new user');
});

// Route for PUT requests to update a resource
app.put('/users/:id', (req, res) => {
  res.send('Received a PUT request to update user with ID: ' + req.params.id);
});

// Route for DELETE requests to delete a resource
app.delete('/users/:id', (req, res) => {
  res.send('Received a DELETE request to delete user with ID: ' + req.params.id);
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
}); 

Handling Different HTTP Methods

Express.js provides specific methods for handling different HTTP request types. Each method corresponds to a standard HTTP verb and triggers different actions on the server.

  • app.get(path, callback): Handles GET requests. Used to retrieve data from the server. Typically used for reading or displaying information.
  • app.post(path, callback): Handles POST requests. Used to send data to the server to create or update a resource. Often used for form submissions or API calls that create new data.
  • app.put(path, callback): Handles PUT requests. Used to replace an existing resource entirely. Requires sending the complete updated resource.
  • app.patch(path, callback): Handles PATCH requests. Used to partially modify an existing resource. Requires sending only the changes that need to be updated.
  • app.delete(path, callback): Handles DELETE requests. Used to delete a resource from the server.
  • app.all(path, callback): Handles all HTTP request methods. Useful for applying middleware to all requests to a specific path.

Choosing the correct HTTP method is crucial for building RESTful APIs and ensuring that your application behaves as expected.

Example: HTTP Method Handlers

 app.get('/products', (req, res) => {
  res.send('List of products');
});

app.post('/products', (req, res) => {
  // Assuming you have middleware to parse the request body (e.g., express.json())
  console.log('Received product data:', req.body);
  res.status(201).send('Product created');
});

app.put('/products/:id', (req, res) => {
  res.send('Updated product with ID: ' + req.params.id);
});

app.delete('/products/:id', (req, res) => {
  res.send('Deleted product with ID: ' + req.params.id);
}); 

Handling URL Parameters

URL parameters allow you to capture dynamic values from the URL. This is essential for creating routes that can handle requests for specific resources or data. In Express.js, URL parameters are defined using a colon (:) followed by the parameter name within the route path.

The captured values are then available in the req.params object within the route handler.

Example: URL Parameters

 app.get('/users/:userId/books/:bookId', (req, res) => {
  const userId = req.params.userId;
  const bookId = req.params.bookId;
  res.send(`User ID: ${userId}, Book ID: ${bookId}`);
});

app.get('/articles/:articleId', (req, res) => {
  const articleId = req.params.articleId;
  res.send(`You are viewing article with ID: ${articleId}`);
}); 

You can also use regular expressions within the route definition for more complex parameter matching:

 app.get('/products/:productId([0-9]+)', (req, res) => {
    // This route will only match if productId is a number
    const productId = req.params.productId;
    res.send(`Product ID: ${productId}`);
}); 

Route Chaining

You can chain multiple route handlers to a single route using app.route(). This is particularly useful when you want to avoid redundant route path declarations.

 app.route('/books/:bookId')
  .get((req, res) => {
    res.send('Get book information for book ID: ' + req.params.bookId);
  })
  .put((req, res) => {
    res.send('Update book with book ID: ' + req.params.bookId);
  })
  .delete((req, res) => {
    res.send('Delete book with book ID: ' + req.params.bookId);
  }); 

Express Router

The express.Router class provides a way to create modular, mountable route handlers. A Router instance is a complete middleware and routing system; for this reason, it is often referred to as a “mini-app”.

 const express = require('express');
const router = express.Router();

// Define routes on the router
router.get('/', (req, res) => {
  res.send('Router example: Get request');
});

router.post('/', (req, res) => {
  res.send('Router example: Post request');
});

module.exports = router;

// In your main app file (e.g., app.js):
// const myRouter = require('./my-router');
// app.use('/my-route', myRouter);