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: 'john@example.com'
};

res.json(user);
});

Output (as JSON):

json
{
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}

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 feedback@compilenrun.com. I’d greatly appreciate your feedback! :)