Skip to main content

Express Response Object

In Express.js applications, the response object (res) is one of the most important tools you have for communicating with clients. This object represents the HTTP response that an Express app sends when it receives an HTTP request.

Introduction to the Response Object

When a client (like a browser or mobile app) makes a request to your Express server, your application needs to send back some kind of response. The res object provides the methods and properties needed to construct and send that response.

The response object is the second parameter passed to your route handlers:

javascript
app.get('/example', (req, res) => {
// 'res' is the response object
// Use it to send a response back to the client
});

Basic Response Methods

res.send()

The most basic method for sending a response is res.send(). It can send various types of responses including strings, objects, arrays, or Buffers.

javascript
app.get('/hello', (req, res) => {
res.send('Hello World!');
});

app.get('/json-example', (req, res) => {
res.send({ message: 'This is a JSON response' });
});

Output for /hello: Plain text "Hello World!" in the browser Output for /json-example: JSON data {"message":"This is a JSON response"}

res.json()

When working with APIs, you'll often want to send JSON data. While res.send() can handle JSON, res.json() is specifically designed for this purpose.

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

Output: [{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]

res.status()

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

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

app.post('/create', (req, res) => {
// After successfully creating a resource
res.status(201).json({ message: 'Resource created successfully' });
});

Common HTTP status codes:

  • 200: OK (default)
  • 201: Created
  • 400: Bad Request
  • 401: Unauthorized
  • 404: Not Found
  • 500: Internal Server Error

Setting Response Headers

res.set() or res.header()

You can set response headers to provide additional information about the response:

javascript
app.get('/custom-header', (req, res) => {
// Setting a single header
res.set('Content-Type', 'text/html');

// Or multiple headers at once
res.set({
'Cache-Control': 'no-store',
'X-Custom-Header': 'Custom value'
});

res.send('<h1>Response with custom headers</h1>');
});

res.type()

A shorthand for setting the Content-Type header:

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

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

Specialized Response Methods

res.render()

When using a template engine (like EJS, Pug, or Handlebars), render compiles a view template and sends the HTML to the client:

javascript
app.get('/profile', (req, res) => {
const userData = {
name: 'John Doe',
email: '[email protected]',
skills: ['JavaScript', 'Node.js', 'Express']
};

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

This requires you to have a template engine set up and a view called 'profile'.

res.redirect()

Redirects the client to a different URL:

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

// Redirect with status code
app.get('/temporary-redirect', (req, res) => {
res.redirect(302, '/destination');
});

// Redirect to external site
app.get('/go-to-google', (req, res) => {
res.redirect('https://www.google.com');
});

res.sendFile()

Sends a file to the client:

javascript
const path = require('path');

app.get('/download/report', (req, res) => {
const filePath = path.join(__dirname, 'files', 'report.pdf');
res.sendFile(filePath);
});

res.download()

Similar to sendFile(), but prompts the browser to download the file rather than display it:

javascript
app.get('/download/document', (req, res) => {
const filePath = path.join(__dirname, 'files', 'document.docx');
res.download(filePath, 'user-document.docx');
});

Working with Cookies

res.cookie()

Sets a cookie value:

javascript
app.get('/set-cookie', (req, res) => {
// Basic cookie
res.cookie('username', 'john_doe');

// Cookie with options
res.cookie('preferences', 'dark_mode', {
maxAge: 86400000, // 24 hours in milliseconds
httpOnly: true, // Not accessible via JavaScript
secure: true, // Only sent over HTTPS
sameSite: 'strict' // CSRF protection
});

res.send('Cookies have been set!');
});

res.clearCookie()

Clears a cookie from the client:

javascript
app.get('/logout', (req, res) => {
res.clearCookie('username');
res.redirect('/login');
});

Ending the Response

res.end()

Ends the response process without sending any data:

javascript
app.get('/empty', (req, res) => {
res.status(204).end();
});

This is useful when you don't want to send any data back, just a status code.

Practical Example: Building a REST API Endpoint

Let's build a more complete example of an API endpoint that demonstrates several response features:

javascript
const express = require('express');
const app = express();

// Sample data
const products = [
{ id: 1, name: 'Laptop', price: 999.99 },
{ id: 2, name: 'Smartphone', price: 699.99 },
{ id: 3, name: 'Headphones', price: 149.99 }
];

// Parse JSON request bodies
app.use(express.json());

// GET all products
app.get('/api/products', (req, res) => {
res.json(products);
});

// GET a single product
app.get('/api/products/:id', (req, res) => {
const productId = parseInt(req.params.id);
const product = products.find(p => p.id === productId);

if (!product) {
return res.status(404).json({
error: 'Product not found'
});
}

res.json(product);
});

// POST a new product
app.post('/api/products', (req, res) => {
// Check if request has required fields
if (!req.body.name || !req.body.price) {
return res.status(400).json({
error: 'Product name and price are required'
});
}

// Create new product
const newProduct = {
id: products.length + 1,
name: req.body.name,
price: req.body.price
};

products.push(newProduct);

// Return successful creation status with the new resource
res.status(201)
.set('Location', `/api/products/${newProduct.id}`)
.json(newProduct);
});

app.listen(3000, () => {
console.log('Server is running on port 3000');
});

This API demonstrates:

  1. Returning collections of data with res.json()
  2. Setting appropriate status codes (200, 201, 404, 400)
  3. Using custom headers (Location) for resource creation
  4. Error responses with meaningful messages

Response Chaining

One powerful feature of Express's response object is method chaining. Most response methods return the response object itself, allowing you to chain multiple methods:

javascript
app.get('/chained-response', (req, res) => {
res.status(200)
.set('X-Custom-Header', 'Value')
.cookie('visited', 'true')
.json({ message: 'This response used chained methods' });
});

Summary

The Express response object provides a rich set of methods for sending data back to clients:

  • Basic response sending: send(), json(), end()
  • Status codes: status()
  • Headers: set(), type()
  • Specialized responses: render(), redirect(), sendFile(), download()
  • Cookie management: cookie(), clearCookie()

Understanding how to use these methods effectively will help you build Express applications that communicate clearly with clients and follow HTTP standards.

Additional Resources

Exercises

  1. Create a route that returns different response formats (HTML, JSON, plain text) based on a query parameter.
  2. Build an API endpoint that demonstrates proper error handling with appropriate status codes.
  3. Create a file download route that serves files from a specific directory with proper error handling.
  4. Implement a route that uses cookies to track how many times a user has visited a page.
  5. Create a middleware that adds custom headers to all responses in your application.


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