Express.js Request Object

In Express.js, the Request object (commonly abbreviated as req) represents the HTTP request sent by a client (like a web browser or a mobile app) to your server. It is the primary way your backend receives information from the outside world. Whether a user is submitting a login form, searching for a product, or uploading a file, that data arrives wrapped inside the req object.

Developer Tip: Think of the Request object as a "message" from the client. Your job as a developer is to read that message, understand what the client wants, and then use the Response object (res) to send an answer back.

 

Key Features of the Request Object

  • Access to Request Data: It acts as a container for all incoming data, including sensitive information like passwords or metadata like the user's browser type.
  • HTTP Method: It identifies what action the client wants to perform (e.g., GET to read data, POST to create data).
  • Route Parameters: It captures dynamic segments of a URL, allowing you to build flexible paths like /user/:id.
  • Query Strings: It handles optional modifiers in the URL, such as search filters or pagination (e.g., ?page=2).
  • Request Body: It holds large amounts of data, usually in JSON format, sent during POST or PUT operations.
  • Request Headers: It provides metadata about the request, such as authentication tokens (JWT) or the content type of the data being sent.

 

Components of the Request Object

req.params
The params object is used to capture dynamic values from the URL path. These are defined in your route using a colon (:) prefix. This is the standard way to identify a specific resource, such as a specific user or a specific blog post.

Example:

app.get('/user/:id', (req, res) => {
    const userId = req.params.id; // Accesses the value passed in the URL
    res.send(`Fetching data for User ID: ${userId}`);
});

If a user visits /user/42, req.params.id will be '42'.

Watch Out: Values in req.params are always returned as strings. If you need to use them as numbers (e.g., for a database lookup), you must convert them using Number() or parseInt().

req.query
The query object handles the query string—the part of the URL that comes after the ?. Query parameters are perfect for optional actions like filtering, sorting, or searching through a list of items.

Example:

app.get('/products', (req, res) => {
    const category = req.query.category;
    const sortBy = req.query.sort;
    res.send(`Showing ${category} sorted by ${sortBy}`);
});

For a request like /products?category=shoes&sort=price, req.query.category will be 'shoes' and req.query.sort will be 'price'.

Best Practice: Use params for required identifiers (like an ID) and query strings for optional modifications (like filters or search terms).

req.body
The body object contains data submitted in the request "payload." This is where you'll find data from submitted HTML forms or JSON objects sent from a frontend framework like React or Vue. By default, Express cannot read the request body; you must use middleware to "parse" it.

Example:

// Required middleware to read JSON bodies
app.use(express.json());

app.post('/register', (req, res) => {
    const { email, password } = req.body; 
    res.send(`Account created for: ${email}`);
});
Common Mistake: Forgetting to add app.use(express.json()) at the top of your file. Without this, req.body will be undefined, and your app will likely crash when you try to access it.

req.headers
The headers object contains the HTTP headers sent by the client. Headers are crucial for security (passing API keys or Bearer tokens) and for telling the server what kind of response the client expects.

Example:

app.get('/api/dashboard', (req, res) => {
    const token = req.headers['authorization'];
    if (!token) {
        return res.status(401).send('Access Denied: No Token Provided');
    }
    res.send('Welcome to the protected dashboard');
});

req.method
This property identifies the HTTP verb used for the request. This is useful if you have a single middleware or route handler that needs to behave differently depending on whether it's a GET, POST, or DELETE request.

req.url
The url property contains the full path of the request. For a request to /api/users?active=true, req.url would return exactly that string. This is often used for logging purposes.

req.cookies
If you are building an application that uses sessions or persistent logins, you will likely use cookies. To read them, you need the cookie-parser middleware. Once installed, req.cookies gives you access to all cookies stored on the client's browser for your domain.

 

Common Use Cases

Accessing Route Parameters
In a RESTful API, you use req.params to define resources. For example, GET /posts/:slug allows you to look up a specific blog post by its URL-friendly title.

Handling Query Strings
E-commerce sites use req.query extensively. When a user filters for "Size: Large" and "Color: Blue," those values are typically pulled from req.query to build a database query.

Handling POST Data
When a user fills out a "Contact Us" form, the data is sent via a POST request. You extract the message, name, and email from req.body to save it to your database.

Authentication
Most modern web apps use the Authorization header to pass a JSON Web Token (JWT). You check req.headers.authorization to verify if a user is logged in before allowing them to see private data.

Developer Tip: Use a tool like Postman or Insomnia to test different request types. It makes it very easy to see how changing headers, bodies, and params affects the req object on your server.

 

Example Code

Here is a complete, runnable example demonstrating how these properties work together in a real Express application:

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

// Essential: Middleware to parse JSON data in req.body
app.use(express.json());

// 1. Using req.params (Dynamic IDs)
app.get('/user/:id', (req, res) => {
    const userId = req.params.id;
    res.json({ message: `Fetching profile for user ${userId}` });
});

// 2. Using req.query (Filtering/Searching)
app.get('/search', (req, res) => {
    const { term, limit } = req.query;
    res.json({ 
        querySent: term, 
        limitRequested: limit || 10 // Default to 10 if not provided
    });
});

// 3. Using req.body (Data submission)
app.post('/api/products', (req, res) => {
    const { name, price } = req.body;
    // Real world: you would save this to a database here
    res.status(201).json({ 
        status: 'Product Created',
        data: { name, price }
    });
});

// 4. Using req.headers (Security/Metadata)
app.get('/admin', (req, res) => {
    const userAgent = req.headers['user-agent'];
    console.log(`Request came from: ${userAgent}`);
    res.send('Admin check logged');
});

// Start the server
const PORT = 3000;
app.listen(PORT, () => {
    console.log(`Server is running at http://localhost:${PORT}`);
});

 

Summary

The request object in Express.js is your window into the client's intent. By mastering req.params, req.query, and req.body, you can handle everything from simple URL navigation to complex data submissions. Always remember to use the appropriate middleware for body parsing and to treat all incoming data as untrusted until validated.