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:
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):
// 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:
// 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):
// 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()
:
// 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:
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:
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:
// 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'):
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:
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:
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:
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:
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
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
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
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:
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 segmentsreq.query
provides access to URL query string parametersreq.body
contains data submitted in the request body (requires body-parsing middleware)req.headers
gives access to HTTP headersreq.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
- Express.js Official Documentation - Request
- Mozilla Developer Network - HTTP request methods
- Express.js middleware guide
Exercises
- Create a route that accepts multiple parameters and query strings, then returns them all as a JSON object.
- Build a basic authentication middleware that checks for a username and password in the request headers.
- Create a route that accepts form data and validates required fields before processing.
- Implement a middleware that logs detailed information about each request (method, path, query parameters, body, etc.).
- 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! :)