Request/Response Handling
Master request and response handling in Express.js applications
45 min•By Priygop Team•Last updated: Feb 2026
Request Object
The request object (req) contains information about the HTTP request that triggered the route handler. It includes properties like headers, body, parameters, and query strings.
Request Properties and Methods
Example
const express = require('express');
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Accessing request properties
app.get('/example', (req, res) => {
// URL and path
console.log('URL:', req.url);
console.log('Path:', req.path);
console.log('Base URL:', req.baseUrl);
// HTTP method
console.log('Method:', req.method);
// Headers
console.log('Headers:', req.headers);
console.log('User Agent:', req.get('User-Agent'));
// Query parameters
console.log('Query:', req.query);
console.log('Search:', req.query.search);
// Route parameters
console.log('Params:', req.params);
// Request body (for POST, PUT, PATCH)
console.log('Body:', req.body);
// IP address
console.log('IP:', req.ip);
// Hostname
console.log('Hostname:', req.hostname);
res.json({ message: 'Request details logged' });
});
// Handling different content types
app.post('/users', (req, res) => {
const { name, email, age } = req.body;
// Validate required fields
if (!name || !email) {
return res.status(400).json({ error: 'Name and email are required' });
}
// Process the data
const user = { name, email, age: age || null };
res.status(201).json({ message: 'User created', user });
});
// File upload handling
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
app.post('/upload', upload.single('file'), (req, res) => {
if (!req.file) {
return res.status(400).json({ error: 'No file uploaded' });
}
res.json({
message: 'File uploaded successfully',
filename: req.file.filename,
originalname: req.file.originalname,
size: req.file.size
});
});Response Object
Example
const express = require('express');
const app = express();
// Sending different response types
app.get('/responses', (req, res) => {
// JSON response
res.json({ message: 'JSON response' });
// HTML response
res.send('<h1>HTML response</h1>');
// Plain text response
res.send('Plain text response');
// Redirect
res.redirect('/new-page');
// Send file
res.sendFile('/path/to/file.html');
// Download file
res.download('/path/to/file.pdf');
});
// Setting response headers
app.get('/headers', (req, res) => {
res.set('Content-Type', 'application/json');
res.set('X-Custom-Header', 'Custom Value');
res.status(200).json({ message: 'Headers set' });
});
// Different HTTP status codes
app.get('/status', (req, res) => {
// Success responses
res.status(200).json({ message: 'OK' });
res.status(201).json({ message: 'Created' });
// Client error responses
res.status(400).json({ error: 'Bad Request' });
res.status(401).json({ error: 'Unauthorized' });
res.status(404).json({ error: 'Not Found' });
// Server error responses
res.status(500).json({ error: 'Internal Server Error' });
res.status(503).json({ error: 'Service Unavailable' });
});
// Streaming responses
app.get('/stream', (req, res) => {
res.setHeader('Content-Type', 'text/plain');
res.setHeader('Transfer-Encoding', 'chunked');
let counter = 0;
const interval = setInterval(() => {
res.write(`Data chunk ${counter}\n`);
counter++;
if (counter >= 10) {
clearInterval(interval);
res.end('Stream complete');
}
}, 1000);
});
// Error responses
app.get('/error', (req, res) => {
try {
// Simulate an error
throw new Error('Something went wrong');
} catch (error) {
res.status(500).json({
error: 'Internal Server Error',
message: error.message
});
}
});Advanced Request/Response Patterns
Example
// Advanced request/response handling patterns
const express = require('express');
const app = express();
// Request streaming for large data
app.get('/stream', (req, res) => {
res.writeHead(200, {
'Content-Type': 'text/plain',
'Transfer-Encoding': 'chunked'
});
let counter = 0;
const interval = setInterval(() => {
res.write(`Chunk ${counter}\n`);
counter++;
if (counter >= 10) {
clearInterval(interval);
res.end('Stream complete');
}
}, 1000);
});
// Response compression
const compression = require('compression');
app.use(compression());
// Custom response methods
app.use((req, res, next) => {
res.success = (data, message = 'Success') => {
res.json({ success: true, message, data });
};
res.error = (message, statusCode = 400) => {
res.status(statusCode).json({ success: false, message });
};
res.paginated = (data, page, limit, total) => {
res.json({
data,
pagination: {
page: parseInt(page),
limit: parseInt(limit),
total,
pages: Math.ceil(total / limit)
}
});
};
next();
});
// Usage of custom response methods
app.get('/api/users', (req, res) => {
const users = [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }];
res.success(users, 'Users retrieved successfully');
});
app.get('/api/posts', (req, res) => {
const { page = 1, limit = 10 } = req.query;
const posts = Array.from({ length: 50 }, (_, i) => ({ id: i + 1, title: `Post ${i + 1}` }));
const start = (page - 1) * limit;
const end = start + parseInt(limit);
const paginatedPosts = posts.slice(start, end);
res.paginated(paginatedPosts, page, limit, posts.length);
});Request/Response Best Practices
- Use appropriate HTTP status codes: 200, 201, 400, 401, 403, 404, 500
- Validate all input: Check request body, query parameters, and headers
- Sanitize data: Clean user input to prevent injection attacks
- Use consistent response format: Standardize JSON response structure
- Handle CORS properly: Configure appropriate CORS headers
- Implement rate limiting: Prevent abuse and DoS attacks
- Use compression: Enable gzip compression for better performance
- Set proper headers: Include security and cache headers
Mini-Project: RESTful API with Advanced Features
Example
// Complete RESTful API with advanced request/response handling
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const compression = require('compression');
const rateLimit = require('express-rate-limit');
const { body, validationResult } = require('express-validator');
const app = express();
// security and performance middleware
app.use(helmet());
app.use(cors());
app.use(compression());
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
app.use('/api/', limiter);
// Custom middleware for request processing
app.use((req, res, next) => {
req.startTime = Date.now();
req.requestId = Math.random().toString(36).substr(2, 9);
// Custom response methods
res.success = (data, message = 'Success', statusCode = 200) => {
res.status(statusCode).json({
success: true,
message,
data,
requestId: req.requestId,
timestamp: new Date().toISOString()
});
};
res.error = (message, statusCode = 400, details = null) => {
res.status(statusCode).json({
success: false,
message,
details,
requestId: req.requestId,
timestamp: new Date().toISOString()
});
};
res.paginated = (data, page, limit, total, message = 'Data retrieved successfully') => {
res.json({
success: true,
message,
data,
pagination: {
page: parseInt(page),
limit: parseInt(limit),
total,
pages: Math.ceil(total / limit),
hasNext: page * limit < total,
hasPrev: page > 1
},
requestId: req.requestId,
timestamp: new Date().toISOString()
});
};
next();
});
// In-memory data store (in real app, use database)
let users = [
{ id: 1, name: 'John Doe', email: 'john@example.com', age: 30, createdAt: new Date() },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', age: 25, createdAt: new Date() }
];
let nextId = 3;
// Validation middleware
const validateUser = [
body('name').isLength({ min: 2 }).withMessage('Name must be at least 2 characters'),
body('email').isEmail().withMessage('Must be a valid email'),
body('age').isInt({ min: 0, max: 150 }).withMessage('Age must be between 0 and 150'),
(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.error('Validation failed', 400, errors.array());
}
next();
}
];
// Routes
app.get('/', (req, res) => {
res.success({
message: 'Welcome to Advanced REST API',
version: '1.0.0',
endpoints: {
users: '/api/users',
health: '/api/health'
}
});
});
app.get('/api/health', (req, res) => {
res.success({
status: 'healthy',
uptime: process.uptime(),
memory: process.memoryUsage(),
timestamp: new Date().toISOString()
});
});
// GET /api/users - Get all users with pagination
app.get('/api/users', (req, res) => {
const { page = 1, limit = 10, search, sortBy = 'id', order = 'asc' } = req.query;
let filteredUsers = users;
// Search functionality
if (search) {
filteredUsers = users.filter(user =>
user.name.toLowerCase().includes(search.toLowerCase()) ||
user.email.toLowerCase().includes(search.toLowerCase())
);
}
// Sorting
filteredUsers.sort((a, b) => {
const aVal = a[sortBy];
const bVal = b[sortBy];
if (order === 'desc') {
return bVal > aVal ? 1 : -1;
}
return aVal > bVal ? 1 : -1;
});
// Pagination
const start = (page - 1) * limit;
const end = start + parseInt(limit);
const paginatedUsers = filteredUsers.slice(start, end);
res.paginated(paginatedUsers, page, limit, filteredUsers.length);
});
// GET /api/users/:id - Get user by ID
app.get('/api/users/:id', (req, res) => {
const { id } = req.params;
const user = users.find(u => u.id === parseInt(id));
if (!user) {
return res.error('User not found', 404);
}
res.success(user);
});
// POST /api/users - Create new user
app.post('/api/users', validateUser, (req, res) => {
const { name, email, age } = req.body;
// Check if email already exists
const existingUser = users.find(u => u.email === email);
if (existingUser) {
return res.error('Email already exists', 409);
}
const newUser = {
id: nextId++,
name,
email,
age: parseInt(age),
createdAt: new Date()
};
users.push(newUser);
res.success(newUser, 'User created successfully', 201);
});
// PUT /api/users/:id - Update user
app.put('/api/users/:id', validateUser, (req, res) => {
const { id } = req.params;
const { name, email, age } = req.body;
const userIndex = users.findIndex(u => u.id === parseInt(id));
if (userIndex === -1) {
return res.error('User not found', 404);
}
// Check if email already exists (excluding current user)
const existingUser = users.find(u => u.email === email && u.id !== parseInt(id));
if (existingUser) {
return res.error('Email already exists', 409);
}
users[userIndex] = {
...users[userIndex],
name,
email,
age: parseInt(age),
updatedAt: new Date()
};
res.success(users[userIndex], 'User updated successfully');
});
// DELETE /api/users/:id - Delete user
app.delete('/api/users/:id', (req, res) => {
const { id } = req.params;
const userIndex = users.findIndex(u => u.id === parseInt(id));
if (userIndex === -1) {
return res.error('User not found', 404);
}
const deletedUser = users.splice(userIndex, 1)[0];
res.success(deletedUser, 'User deleted successfully');
});
// Error handling middleware
app.use((err, req, res, next) => {
console.error(`[${req.requestId}] Error:`, err);
if (err.type === 'entity.parse.failed') {
return res.error('Invalid JSON in request body', 400);
}
res.error('Internal server error', 500);
});
// 404 handler
app.use((req, res) => {
res.error('Route not found', 404);
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
console.log(`API Documentation: http://localhost:${PORT}`);
});
module.exports = app;