Skip to main content

Express Request Object

Introduction

When building web applications with Express.js, understanding how to work with HTTP requests is fundamental. The Express Request object (req) is a core component that provides all the information about the incoming HTTP request from the client. It contains data about the request parameters, query strings, headers, body, and more.

In this tutorial, we'll dive deep into the Express Request object, explore its properties and methods, and learn how to leverage it effectively in your Express applications.

What is the Request Object?

The Request object is automatically created by Express when a client makes a request to your server. It's the first parameter in Express route handlers and middleware functions:

javascript
app.get('/users', (req, res) => {
// 'req' is the Request object
// 'res' is the Response object

res.send('Hello, World!');
});

The req object contains valuable information about the client's request and provides methods to access and manipulate that data.

Common Request Properties

Let's explore the most commonly used properties of the Express Request object:

req.params

The req.params object contains route parameters (URL segments that are captured):

javascript
// Route: /users/:id
app.get('/users/:id', (req, res) => {
console.log(req.params.id); // If URL is /users/123, this outputs: 123

res.send(`User ID: ${req.params.id}`);
});

You can define multiple route parameters:

javascript
// Route: /users/:userId/posts/:postId
app.get('/users/:userId/posts/:postId', (req, res) => {
console.log(req.params.userId); // e.g., "123"
console.log(req.params.postId); // e.g., "456"

res.send(`Fetching post ${req.params.postId} from user ${req.params.userId}`);
});

req.query

The req.query object contains the URL query string parameters (after the ? in the URL):

javascript
// URL: /search?q=express&limit=10
app.get('/search', (req, res) => {
console.log(req.query.q); // "express"
console.log(req.query.limit); // "10"

res.send(`You searched for: ${req.query.q}`);
});

req.body

The req.body property contains key-value pairs of data submitted in the request body. By default, it's undefined and populated when you use body-parsing middleware like express.json() or express.urlencoded():

javascript
// First, add the middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Then, access req.body in your route handler
app.post('/users', (req, res) => {
console.log(req.body.name); // e.g., "John Doe"
console.log(req.body.email); // e.g., "[email protected]"

res.send(`User ${req.body.name} created!`);
});

req.headers

The req.headers object contains the HTTP headers sent by the client:

javascript
app.get('/api/data', (req, res) => {
console.log(req.headers); // All headers
console.log(req.headers['user-agent']); // Browser/client info
console.log(req.headers.authorization); // Auth header if present

res.send('Headers received');
});

req.cookies

If you use the cookie-parser middleware, req.cookies contains cookies sent by the client:

javascript
const cookieParser = require('cookie-parser');

app.use(cookieParser());

app.get('/profile', (req, res) => {
console.log(req.cookies.username); // Value of the 'username' cookie

res.send(`Hello, ${req.cookies.username || 'Guest'}`);
});

req.path

Contains the path part of the request URL:

javascript
// URL: http://example.com/users?sort=asc
app.get('/users', (req, res) => {
console.log(req.path); // "/users"

res.send('User list');
});

req.protocol

Contains the request protocol string ('http' or 'https'):

javascript
app.get('/', (req, res) => {
console.log(req.protocol); // "http" or "https"

res.send(`Protocol: ${req.protocol}`);
});

req.hostname

Contains the hostname from the Host HTTP header:

javascript
app.get('/', (req, res) => {
console.log(req.hostname); // e.g., "example.com"

res.send(`Hostname: ${req.hostname}`);
});

Request Methods

In addition to properties, the Request object provides several useful methods:

req.get()

Retrieves the specified HTTP request header:

javascript
app.get('/api/data', (req, res) => {
const contentType = req.get('Content-Type');
console.log(contentType); // e.g., "application/json"

res.send(`Content Type: ${contentType}`);
});

req.accepts()

Checks if the specified content types are acceptable based on the request's Accept HTTP header:

javascript
app.get('/api/data', (req, res) => {
if (req.accepts('html')) {
res.send('<h1>Data</h1>');
} else if (req.accepts('json')) {
res.json({ data: 'Some data' });
} else {
res.send('Data');
}
});

req.is()

Checks if the incoming request's Content-Type matches the specified type:

javascript
app.post('/api/data', (req, res) => {
if (req.is('json')) {
// Handle JSON data
res.send('Received JSON data');
} else if (req.is('application/x-www-form-urlencoded')) {
// Handle form data
res.send('Received form data');
} else {
res.status(415).send('Unsupported Media Type');
}
});

Practical Examples

Let's look at some practical examples to see how the Request object is used in real-world scenarios.

Example 1: Building a RESTful API

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

app.use(express.json());

// Sample in-memory database
const users = [
{ id: 1, name: 'Alice', email: '[email protected]' },
{ id: 2, name: 'Bob', email: '[email protected]' }
];

// Get all users
app.get('/api/users', (req, res) => {
// Check if there's a search query
const search = req.query.search;

if (search) {
const filteredUsers = users.filter(user =>
user.name.toLowerCase().includes(search.toLowerCase())
);
return res.json(filteredUsers);
}

res.json(users);
});

// Get user by id
app.get('/api/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
const user = users.find(u => u.id === userId);

if (!user) {
return res.status(404).json({ error: 'User not found' });
}

res.json(user);
});

// Create a new user
app.post('/api/users', (req, res) => {
// Validate request body
if (!req.body.name || !req.body.email) {
return res.status(400).json({ error: 'Name and email are required' });
}

const newUser = {
id: users.length + 1,
name: req.body.name,
email: req.body.email
};

users.push(newUser);
res.status(201).json(newUser);
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Example 2: Authentication Middleware

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

// Middleware to check for API key
function apiKeyAuth(req, res, next) {
// Get API key from headers, query, or wherever it's sent
const apiKey = req.get('X-API-Key') || req.query.apiKey;

if (!apiKey) {
return res.status(401).json({ error: 'API key is required' });
}

if (apiKey !== 'your-secret-api-key') {
return res.status(403).json({ error: 'Invalid API key' });
}

// Store authenticated status in req object for later middleware or routes
req.isAuthenticated = true;
next();
}

// Protected route
app.get('/api/protected', apiKeyAuth, (req, res) => {
res.json({ message: 'You accessed protected data!', isAuthenticated: req.isAuthenticated });
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Example 3: File Upload with Express

javascript
const express = require('express');
const multer = require('multer');
const path = require('path');
const app = express();

// Configure storage
const storage = multer.diskStorage({
destination: './uploads/',
filename: (req, file, cb) => {
cb(null, `${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`);
}
});

// Initialize upload
const upload = multer({
storage: storage,
limits: { fileSize: 1000000 }, // 1MB limit
fileFilter: (req, file, cb) => {
// Check file types
const filetypes = /jpeg|jpg|png|gif/;
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = filetypes.test(file.mimetype);

if (mimetype && extname) {
return cb(null, true);
} else {
cb('Error: Images only!');
}
}
}).single('image'); // 'image' is the name of the input field

app.post('/upload', (req, res) => {
upload(req, res, (err) => {
if (err) {
res.status(400).json({ error: err });
} else {
if (req.file == undefined) {
res.status(400).json({ error: 'No file selected!' });
} else {
res.json({
success: true,
message: 'File uploaded!',
file: {
name: req.file.filename,
mimetype: req.file.mimetype,
size: req.file.size
}
});
}
}
});
});

app.listen(3000, () => {
console.log('Server running on port 3000');
});

Custom Properties

You can add custom properties to the req object in middleware functions, making them available to subsequent middleware and route handlers:

javascript
app.use((req, res, next) => {
// Add a timestamp to every request
req.requestTime = Date.now();
next();
});

app.get('/', (req, res) => {
res.send(`Request received at: ${new Date(req.requestTime)}`);
});

This is a powerful pattern for passing data between middleware functions.

Summary

The Express Request object is a versatile and powerful component that provides access to all the information about the incoming HTTP request. Understanding how to leverage its properties and methods is crucial for building efficient Express applications.

Key points to remember:

  • req.params captures route parameters from URL segments
  • req.query provides access to URL query string parameters
  • req.body contains data submitted in the request body (requires body-parsing middleware)
  • req.headers gives access to HTTP headers
  • req.cookies contains cookies (requires cookie-parser middleware)
  • The Request object can be extended with custom properties in middleware

By mastering the Request object, you gain full control over how your Express application processes incoming requests, enabling you to build robust, feature-rich web applications.

Additional Resources

Exercises

  1. Create a route that accepts multiple parameters and query strings, then returns them all as a JSON object.
  2. Build a basic authentication middleware that checks for a username and password in the request headers.
  3. Create a route that accepts form data and validates required fields before processing.
  4. Implement a middleware that logs detailed information about each request (method, path, query parameters, body, etc.).
  5. Build a route that responds differently based on the Accept header in the request.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)