Skip to main content

Express Response Methods

When building web applications with Express.js, effectively managing how your server responds to client requests is crucial. Express provides a rich set of response methods that allow you to send different types of data back to clients in various formats. This guide will walk you through these response methods and show you how to use them in your applications.

Introduction to Response Object

In Express.js, the response object (conventionally named res) represents the HTTP response that an Express app sends when it receives an HTTP request. The response object comes with numerous methods that allow you to:

  • Send different types of content
  • Set HTTP headers
  • Control response status
  • Redirect users
  • End the request-response cycle

Let's explore these methods in detail.

Basic Response Methods

res.send()

The res.send() method is the most versatile response method in Express. It can send responses of various types including strings, HTML, arrays, and objects.

js
app.get('/basic', (req, res) => {
// Sending a string response
res.send('Hello World!');
});

app.get('/html', (req, res) => {
// Sending HTML
res.send('<h1>Hello World!</h1>');
});

app.get('/json-auto', (req, res) => {
// Sending an object (automatically converts to JSON)
res.send({ message: 'Success', data: [1, 2, 3] });
});

When res.send() is called with an object or array, Express automatically:

  1. Converts the data to JSON
  2. Sets the Content-Type header to application/json

res.json()

The res.json() method explicitly sends a JSON response. It performs automatic conversion of non-objects like null and undefined which would cause errors with JSON.stringify().

js
app.get('/user', (req, res) => {
const user = {
name: 'John Doe',
age: 30,
roles: ['user', 'admin']
};

res.json(user);
});

// Even works with non-objects
app.get('/null-response', (req, res) => {
res.json(null); // Valid - will send 'null' as JSON
});

Output of /user:

json
{
"name": "John Doe",
"age": 30,
"roles": ["user", "admin"]
}

res.end()

The res.end() method ends the response process without sending any data.

js
app.get('/end-example', (req, res) => {
// Perhaps some processing happened...
res.end(); // Ends response with no data
});

This method is useful when you need to end the response without providing any data, such as when responding to certain types of requests or after handling errors.

Setting Status Codes

res.status()

The res.status() method sets the HTTP status code for the response. It returns the response object, allowing you to chain other methods.

js
app.get('/success', (req, res) => {
res.status(200).send('Success!');
});

app.get('/not-found', (req, res) => {
res.status(404).send('Resource not found');
});

app.post('/created', (req, res) => {
res.status(201).json({ message: 'Resource created' });
});

res.sendStatus()

The res.sendStatus() method sets the status code and sends its string representation as the response body.

js
app.get('/unauthorized', (req, res) => {
res.sendStatus(401);
// Equivalent to: res.status(401).send('Unauthorized')
});

Output: Unauthorized

Specialized Response Methods

res.render()

The res.render() method renders a view template and sends the HTML to the client. This requires a view engine to be configured.

js
// First, set up a view engine
app.set('view engine', 'ejs');
app.set('views', './views');

// Then use res.render to send rendered HTML
app.get('/profile', (req, res) => {
const userData = {
username: 'devUser',
email: '[email protected]',
isAdmin: true
};

res.render('profile', userData);
});

This will render the profile.ejs template (or whatever view engine you're using) with the provided data and send the resulting HTML to the client.

res.download()

The res.download() method prompts the user to download a file from the server.

js
app.get('/download-report', (req, res) => {
const filePath = './reports/monthly-report.pdf';

res.download(filePath, 'monthly-report.pdf', (err) => {
if (err) {
// Handle error, but don't forget response is already sent
console.error('Download error:', err);
} else {
// Download successful
console.log('Download initiated');
}
});
});

res.sendFile()

The res.sendFile() method transfers a file as an attachment or to be displayed in the browser, depending on the client's handling.

js
app.get('/view-image', (req, res) => {
const imagePath = path.join(__dirname, 'public/images/logo.png');

res.sendFile(imagePath, (err) => {
if (err) {
console.error('Error sending file:', err);
res.status(500).send('Error sending file');
}
});
});

res.redirect()

The res.redirect() method redirects the client to a different URL. By default, it uses HTTP status code 302 (Found).

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

// Redirect with custom status code (301 - Moved Permanently)
app.get('/permanent-redirect', (req, res) => {
res.redirect(301, '/new-location');
});

// Redirect to external URL
app.get('/external', (req, res) => {
res.redirect('https://expressjs.com');
});

Working with Headers

res.set() or res.header()

These methods set response HTTP headers.

js
app.get('/custom-headers', (req, res) => {
res.set({
'Content-Type': 'text/plain',
'X-Custom-Header': 'Custom Value',
'Cache-Control': 'no-store'
});

// You can also set headers individually
res.set('X-Powered-By', 'Your App Name');

res.send('Response with custom headers');
});

res.type()

The res.type() method is a shorthand for setting the Content-Type header.

js
app.get('/text', (req, res) => {
res.type('text/plain');
res.send('Plain text response');
});

app.get('/html-explicit', (req, res) => {
res.type('html');
res.send('<h1>HTML Response</h1>');
});

// For common mime types, you can use shortcuts
app.get('/json-explicit', (req, res) => {
res.type('json');
res.send({ message: 'JSON response' });
});

Practical Examples

Building a REST API Endpoint

js
app.get('/api/users', (req, res) => {
try {
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' }
];

res.status(200).json(users);
} catch (error) {
res.status(500).json({
error: 'Internal server error',
details: error.message
});
}
});

app.post('/api/users', (req, res) => {
try {
// Imagine we're creating a user in a database
const newUser = {
id: 4,
name: req.body.name
};

// Respond with 201 Created status and the new resource
res.status(201).json(newUser);
} catch (error) {
res.status(400).json({
error: 'Invalid user data',
details: error.message
});
}
});

Serving Different Content Types Based on Request

js
app.get('/resource', (req, res) => {
const data = {
name: 'Example Resource',
description: 'This is an example',
created: new Date()
};

// Check Accept header
const acceptHeader = req.get('Accept');

if (acceptHeader && acceptHeader.includes('application/xml')) {
// Very simple XML conversion for demonstration
const xml = `
<resource>
<name>${data.name}</name>
<description>${data.description}</description>
<created>${data.created}</created>
</resource>
`;

res.type('application/xml');
res.send(xml);
} else {
// Default to JSON
res.json(data);
}
});

Error Handling Page

js
app.get('/protected', (req, res) => {
const isAuthenticated = false; // Simulate authentication check

if (!isAuthenticated) {
return res.status(403).render('error', {
title: 'Access Denied',
message: 'You need to login to view this page',
actionLink: '/login',
actionText: 'Login Now'
});
}

res.send('Protected content');
});

Chaining Response Methods

One powerful feature of Express response methods is that many of them return the response object, allowing you to chain them together:

js
app.get('/chained', (req, res) => {
res
.status(200)
.set('X-Custom-Header', 'Value')
.type('json')
.send({ message: 'All methods chained!' });
});

This makes your code more concise and readable.

Common Response Patterns

Conditional Responses

js
app.get('/feature', (req, res) => {
const version = req.query.version;

if (version === 'v2') {
return res.json({ newFeature: true, message: 'Welcome to v2!' });
}

// Default to v1 response
res.json({ feature: 'basic' });
});

Streaming Responses

For large files or real-time data, you can use Express to stream responses:

js
const fs = require('fs');

app.get('/stream-video', (req, res) => {
const videoPath = './videos/sample.mp4';
const stat = fs.statSync(videoPath);

res.writeHead(200, {
'Content-Type': 'video/mp4',
'Content-Length': stat.size
});

const videoStream = fs.createReadStream(videoPath);
videoStream.pipe(res);
});

Summary

Express.js provides a rich set of response methods that give you fine-grained control over HTTP responses:

  • res.send() and res.json() for sending basic responses
  • res.status() for setting HTTP status codes
  • res.render() for template rendering
  • res.download() and res.sendFile() for file transfers
  • res.redirect() for URL redirects
  • Header manipulation methods like res.set() and res.type()

Understanding these methods allows you to build more sophisticated web applications that can respond appropriately to different client requests.

Additional Resources and Exercises

Resources

  1. Express.js Official Documentation on Response
  2. MDN HTTP Response Status Codes
  3. Best Practices for REST API Design

Exercises

  1. Basic Response Exercise: Create an Express route that returns different responses based on a query parameter. If ?format=json is provided, return JSON data; otherwise, return HTML.

  2. Status Code Practice: Build a route that simulates different HTTP status codes. Allow the client to request a specific status code via URL parameter and respond accordingly with both the status and an appropriate message.

  3. Content Negotiation: Implement a route that serves the same resource in different formats (JSON, XML, HTML) based on the Accept header from the request.

  4. Error Handling: Create a middleware function that catches errors in your routes and sends appropriate status codes and error messages using the response methods we've covered.

  5. File Download System: Build a simple file manager API that lists available files and allows downloading them using the appropriate response methods.

By practicing with these exercises, you'll gain hands-on experience with Express response methods and be better prepared to build robust web applications.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)