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:
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.
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.
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.
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:
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:
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:
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:
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:
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:
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:
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:
app.get('/logout', (req, res) => {
res.clearCookie('username');
res.redirect('/login');
});
Ending the Response
res.end()
Ends the response process without sending any data:
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:
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:
- Returning collections of data with
res.json()
- Setting appropriate status codes (200, 201, 404, 400)
- Using custom headers (Location) for resource creation
- 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:
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
- Create a route that returns different response formats (HTML, JSON, plain text) based on a query parameter.
- Build an API endpoint that demonstrates proper error handling with appropriate status codes.
- Create a file download route that serves files from a specific directory with proper error handling.
- Implement a route that uses cookies to track how many times a user has visited a page.
- 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! :)