Express Response Object
Introduction
When building web applications with Express.js, you need to handle both incoming requests and outgoing responses. The Express Response object (res
) is a crucial component that allows you to send data back to the client, set response headers, manage cookies, and control the flow of your HTTP responses.
The Response object extends Node.js's native HTTP response object, adding several helpful methods that make it easier to send different types of responses to clients. Whether you're building APIs or rendering web pages, understanding the Response object is essential for creating effective Express applications.
Basic Response Methods
Sending Basic Responses
The most common thing you'll do with the Response object is send data back to the client.
Send a Simple Response
The res.send()
method is the Swiss Army knife of response methods—it can send strings, HTML, JSON, and more:
app.get('/hello', (req, res) => {
res.send('Hello World!');
});
When a user visits /hello
, they'll see:
Hello World!
Sending HTML
You can also send HTML directly:
app.get('/html', (req, res) => {
res.send('<h1>This is HTML</h1><p>Express makes it easy to send HTML responses!</p>');
});
Sending JSON
For APIs, the res.json()
method automatically converts JavaScript objects to JSON and sets the appropriate content-type headers:
app.get('/api/user', (req, res) => {
const user = {
id: 1,
name: 'John Doe',
email: '[email protected]'
};
res.json(user);
});
Output (as JSON):
{
"id": 1,
"name": "John Doe",
"email": "[email protected]"
}
Ending the Response
Sometimes you may want to end the response without sending data:
app.get('/empty', (req, res) => {
// Do some processing
res.end();
});
Setting Response Status Codes
HTTP status codes inform the client about the result of their request. Express makes it easy to set these:
Setting Status with Chain Methods
You can chain the status()
method with other methods:
app.get('/not-found', (req, res) => {
res.status(404).send('Resource not found');
});
Common Status Code Methods
Express provides shorthand methods for common status codes:
// Sends a 200 OK response
app.get('/ok', (req, res) => {
res.sendStatus(200);
// Equivalent to: res.status(200).send('OK')
});
// Sends a 404 Not Found response
app.get('/missing', (req, res) => {
res.sendStatus(404);
// Equivalent to: res.status(404).send('Not Found')
});
Response Headers
Headers provide additional information about the response. They control caching, security, content types, and more.
Setting Headers
app.get('/pdf-file', (req, res) => {
res.set('Content-Type', 'application/pdf');
// or using the alternate method:
res.header('Content-Disposition', 'attachment; filename=report.pdf');
// Send the actual PDF content here
res.send(pdfBuffer);
});
Multiple Headers at Once
app.get('/api/secured', (req, res) => {
res.set({
'Content-Type': 'application/json',
'X-API-Key': 'generated-key',
'Cache-Control': 'no-store'
});
res.send({ secure: true, data: 'Protected content' });
});
File Downloads and Attachments
Express makes it simple to send files as downloadable attachments:
Sending a File Download
app.get('/download/report', (req, res) => {
res.download('./files/report.pdf', 'quarterly-report.pdf', (err) => {
if (err) {
// Handle error, but keep in mind the response may already be partially sent
console.error('Error during download:', err);
if (!res.headersSent) {
return res.status(500).send('Download error');
}
}
});
});
Serving Static Files
For simple file sending without download prompts:
app.get('/file', (req, res) => {
res.sendFile('/path/to/file.txt', { root: __dirname });
});
Working with Cookies
Cookies allow you to store data in the client's browser, which is sent with every request.
Setting Cookies
app.get('/set-cookie', (req, res) => {
// Simple cookie
res.cookie('username', 'john_doe');
// Cookie with options
res.cookie('preferences', 'dark-mode', {
maxAge: 900000, // 15 minutes in milliseconds
httpOnly: true, // Can't be accessed by client-side JavaScript
secure: true, // Sent only over HTTPS
sameSite: 'strict' // CSRF protection
});
res.send('Cookies have been set!');
});
Clearing Cookies
app.get('/logout', (req, res) => {
res.clearCookie('username');
res.send('Logged out!');
});
Redirects
Redirects are crucial for routing users to the correct pages after actions like form submissions or authentication.
Basic Redirect
app.get('/old-page', (req, res) => {
res.redirect('/new-page');
});
Redirect with Status Code
app.get('/temporary-redirect', (req, res) => {
res.redirect(302, '/target-page');
});
app.get('/permanent-redirect', (req, res) => {
res.redirect(301, '/new-home');
});
Relative Redirects
app.get('/products', (req, res) => {
// Redirect relative to the current route
// If current URL is /products, this redirects to /products/featured
res.redirect('featured');
});
Rendering Views
If you're using a template engine like EJS, Pug, or Handlebars, you can render views using the render()
method:
app.get('/dashboard', (req, res) => {
const userData = {
name: 'John',
tasks: ['Learn Express', 'Build an API', 'Create a portfolio']
};
res.render('dashboard', userData);
});
Real-World Example: Building a Complete API Endpoint
Let's put it all together with a more comprehensive example of an API endpoint:
// Product API endpoint
app.get('/api/products/:id', (req, res) => {
const productId = req.params.id;
// Simulate database lookup
getProductFromDatabase(productId)
.then(product => {
if (!product) {
return res.status(404).json({
success: false,
message: `Product with ID ${productId} not found`
});
}
// Set cache header for successful responses
res.set('Cache-Control', 'public, max-age=300'); // Cache for 5 minutes
// Add a custom header
res.set('X-API-Version', '1.2');
// Send successful response
res.status(200).json({
success: true,
data: product
});
})
.catch(error => {
console.error('Database error:', error);
res.status(500).json({
success: false,
message: 'Internal server error',
error: process.env.NODE_ENV === 'development' ? error.message : undefined
});
});
});
// Simulated function
function getProductFromDatabase(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (id === '404') {
resolve(null); // Simulate product not found
} else if (id === '500') {
reject(new Error('Database connection failed')); // Simulate error
} else {
resolve({
id: id,
name: `Product ${id}`,
price: Math.floor(Math.random() * 100) + 1,
inStock: true
});
}
}, 100);
});
}
This example demonstrates handling successful responses, error scenarios, setting appropriate status codes, and using custom headers.
Summary
The Express Response object is a powerful tool for creating dynamic and robust web applications. It allows you to:
- Send various types of data (text, HTML, JSON, files) back to the client
- Set status codes to indicate success, redirection, or error states
- Manage response headers for controlling caching, security, and content types
- Work with cookies for client-side data storage
- Redirect users to different pages
- Render views using template engines
By mastering the Response object, you'll be able to create more sophisticated and user-friendly web applications and APIs.
Additional Resources
Practice Exercises
- Create an endpoint that returns different content types based on a query parameter (
?format=json
or?format=html
) - Build a file download system that serves files from a protected directory after checking authorization
- Create a response helper that standardizes API responses with consistent formatting for success and error cases
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)