Express Request Object
Introduction
When building web applications with Express.js, one of the most fundamental concepts to understand is the Request object. This object contains all the information about the incoming HTTP request from a client to your server. Mastering the Request object is crucial for handling user input, processing data, and creating dynamic web applications.
The Request object (often written as req
in Express applications) is automatically created by Express whenever a client makes a request to your server. It contains properties and methods that help you access request parameters, headers, body content, and much more.
In this tutorial, we'll explore the Express Request object in depth, understand its key properties and methods, and see how to use it effectively in your applications.
Understanding the Express Request Object
The Request object is the first parameter in the Express route handler callback function. Here's a basic example:
app.get('/hello', (req, res) => {
// 'req' is the Request object
// 'res' is the Response object
res.send('Hello World!');
});
The req
object contains all the information about the incoming HTTP request, making it a powerful tool for building dynamic applications.
Common Properties of the Request Object
req.params
The req.params
property contains route parameters (named URL segments that capture values specified at their position in the URL).
// Route: /users/:userId/books/:bookId
app.get('/users/:userId/books/:bookId', (req, res) => {
console.log(req.params.userId); // Access the userId parameter
console.log(req.params.bookId); // Access the bookId parameter
res.send(`You requested user ${req.params.userId}'s book: ${req.params.bookId}`);
});
Example Input: A request to /users/34/books/8989
Example Output:
You requested user 34's book: 8989
In the server console:
34
8989
req.query
The req.query
property is an object containing the parsed query string parameters from the URL.
// Route: /search
app.get('/search', (req, res) => {
const query = req.query.q;
const category = req.query.category || 'all';
res.send(`Searching for "${query}" in category: ${category}`);
});
Example Input: A request to /search?q=express&category=javascript
Example Output:
Searching for "express" in category: javascript
req.body
The req.body
property contains the parsed request body. To access this, you need to use a middleware like express.json()
or express.urlencoded()
.
// First, add middleware to parse JSON bodies
app.use(express.json());
app.post('/api/users', (req, res) => {
const { name, email, age } = req.body;
console.log(`Name: ${name}, Email: ${email}, Age: ${age}`);
// Process the data...
res.status(201).send(`User ${name} created successfully!`);
});
Example Input:
POST request to /api/users
with JSON body:
{
"name": "John Doe",
"email": "[email protected]",
"age": 28
}
Example Output:
User John Doe created successfully!
In the server console:
Name: John Doe, Email: [email protected], Age: 28
req.headers
The req.headers
property contains all the HTTP headers from the request.
app.get('/headers', (req, res) => {
const userAgent = req.headers['user-agent'];
const contentType = req.headers['content-type'];
res.send(`Your User-Agent is: ${userAgent}\nContent-Type: ${contentType || 'Not specified'}`);
});
Example Output:
Your User-Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...
Content-Type: Not specified
req.cookies
If you use the cookie-parser
middleware, req.cookies
will contain cookies sent by the client.
const cookieParser = require('cookie-parser');
app.use(cookieParser());
app.get('/cookies', (req, res) => {
const sessionId = req.cookies.sessionId;
res.send(`Your session ID is: ${sessionId || 'No session found'}`);
});
Request Methods
Besides properties, the Request object provides several useful methods:
req.get()
Retrieves the value of a specified HTTP request header.
app.get('/api/data', (req, res) => {
const acceptHeader = req.get('Accept');
console.log(`Accept header: ${acceptHeader}`);
res.send('Header received!');
});
req.is()
Checks if the request's Content-Type header matches the specified type.
app.post('/api/profile', (req, res) => {
if (req.is('application/json')) {
// Handle JSON input
res.send('Received JSON data');
} else if (req.is('multipart/form-data')) {
// Handle form data
res.send('Received form data');
} else {
res.status(415).send('Unsupported Media Type');
}
});
req.originalUrl
, req.path
, and req.baseUrl
These properties help you inspect different parts of the request URL.
// In a router mounted at '/blog'
app.get('/blog/posts/:id', (req, res) => {
console.log(req.originalUrl); // e.g., '/blog/posts/123?format=html'
console.log(req.baseUrl); // '/blog'
console.log(req.path); // '/posts/123'
console.log(req.hostname); // e.g., 'example.com'
console.log(req.protocol); // e.g., 'http'
res.send('URL info logged');
});
Practical Examples
Example 1: User Authentication
This example shows how to handle user login using the request body:
app.use(express.json());
app.post('/login', (req, res) => {
const { username, password } = req.body;
// In a real app, you would verify against a database
if (username === 'admin' && password === 'secure123') {
res.status(200).json({ success: true, message: 'Login successful' });
} else {
res.status(401).json({ success: false, message: 'Invalid credentials' });
}
});
Example 2: RESTful API with Route Parameters
// Get a specific product
app.get('/api/products/:id', (req, res) => {
const productId = req.params.id;
// In a real app, fetch from database
const product = { id: productId, name: 'Sample Product', price: 99.99 };
res.json(product);
});
// Update a product
app.put('/api/products/:id', (req, res) => {
const productId = req.params.id;
const updates = req.body;
console.log(`Updating product ${productId} with:`, updates);
// In a real app, update in database
res.json({
success: true,
message: `Product ${productId} updated successfully`,
updates
});
});
Example 3: File Upload with Request
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
app.post('/upload', upload.single('photo'), (req, res) => {
// req.file contains information about the uploaded file
if (!req.file) {
return res.status(400).send('No file uploaded');
}
res.send({
message: 'File uploaded successfully',
filename: req.file.filename,
originalName: req.file.originalname,
size: req.file.size
});
});
Example 4: Working with Query Parameters for Filtering
app.get('/api/products', (req, res) => {
// Extract query parameters
const category = req.query.category;
const minPrice = parseFloat(req.query.minPrice) || 0;
const maxPrice = parseFloat(req.query.maxPrice) || Number.MAX_VALUE;
// In a real app, you'd query a database
const products = [
{ id: 1, name: 'Laptop', category: 'electronics', price: 1200 },
{ id: 2, name: 'Book', category: 'books', price: 20 },
{ id: 3, name: 'Phone', category: 'electronics', price: 600 }
];
// Filter products based on query parameters
const filteredProducts = products.filter(product => {
if (category && product.category !== category) return false;
if (product.price < minPrice || product.price > maxPrice) return false;
return true;
});
res.json(filteredProducts);
});
Security Considerations
When working with the Request object, always be mindful of security:
-
Input Validation: Always validate and sanitize data from
req.body
,req.params
, andreq.query
to prevent injection attacks. -
Rate Limiting: Consider implementing rate limiting to prevent abuse.
-
CSRF Protection: For form submissions, implement CSRF (Cross-Site Request Forgery) protection.
-
Content Security Policy: Set appropriate headers to mitigate XSS attacks.
Example of basic input validation:
app.post('/api/user', (req, res) => {
const { name, email, age } = req.body;
// Basic validation
if (!name || name.length < 2) {
return res.status(400).json({ error: 'Name is required and must be at least 2 characters' });
}
if (!email || !email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) {
return res.status(400).json({ error: 'Valid email is required' });
}
if (age !== undefined && (isNaN(age) || age < 0)) {
return res.status(400).json({ error: 'Age must be a positive number' });
}
// Process valid data
res.status(201).json({ success: true, message: 'User created' });
});
Summary
The Express Request object is a powerful interface to the incoming HTTP request in your Express application. It provides access to:
- Route parameters via
req.params
- Query string parameters via
req.query
- Request body data via
req.body
(with appropriate middleware) - HTTP headers via
req.headers
- Cookies via
req.cookies
(with cookie-parser middleware) - Various methods and properties for URL information and content negotiation
Understanding how to effectively use the Request object is essential for building dynamic, interactive web applications with Express.js. With the examples and knowledge from this guide, you should now be well-equipped to handle various types of user input and create robust request handling logic in your Express applications.
Practice Exercises
-
Create a simple Express route that accepts a username as a route parameter and responds with a personalized greeting.
-
Build an API endpoint that accepts query parameters for pagination (limit and offset) and returns a subset of items.
-
Create a form submission handler that validates input from a registration form (name, email, password) and returns appropriate success or error messages.
-
Implement a route that reads and responds differently based on the Accept header in the request.
Additional Resources
- Express.js Official Documentation
- MDN Web Docs: HTTP Headers
- OWASP: Input Validation Cheat Sheet
- Express.js Security Best Practices
Remember that mastering the Request object is just one part of becoming proficient with Express.js. As you continue your journey, explore how the Request object interacts with middleware, routing, and the Response object to build complete web applications.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)