Skip to main content

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:

javascript
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:

javascript
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:

javascript
app.get('/api/user', (req, res) => {
const user = {
id: 1,
name: 'John Doe',
email: '[email protected]'
};

res.json(user);
});

Output (as JSON):

json
{
"id": 1,
"name": "John Doe",
"email": "[email protected]"
}

Ending the Response

Sometimes you may want to end the response without sending data:

javascript
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:

javascript
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:

javascript
// 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

javascript
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

javascript
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

javascript
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:

javascript
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

javascript
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

javascript
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

javascript
app.get('/old-page', (req, res) => {
res.redirect('/new-page');
});

Redirect with Status Code

javascript
app.get('/temporary-redirect', (req, res) => {
res.redirect(302, '/target-page');
});

app.get('/permanent-redirect', (req, res) => {
res.redirect(301, '/new-home');
});

Relative Redirects

javascript
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:

javascript
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:

javascript
// 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

  1. Create an endpoint that returns different content types based on a query parameter (?format=json or ?format=html)
  2. Build a file download system that serves files from a protected directory after checking authorization
  3. 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! :)