The res Object in Express

Jul 17, 2019

The 2nd parameter to Express route handlers and middleware functions is the Express response object, commonly called res. The res object exposes several functions that let you configure and send a response to an HTTP request.

Basic Response Using res.send()

The res.send() function is the most basic way to send an HTTP response. Calling res.send() with a string sends a response with the string as the response body and content type set to 'text/html; charset=utf-8'.

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

app.get('*', function(req, res) {
  res.send('Hello, World');
});

const server = await app.listen(3000);

const response = await axios.get('http://localhost:3000');
response.data; // 'Hello, World'
response.headers['content-type']; // 'text/html; charset=utf-8'

JSON Responses Using res.json()

The res.send() function is rarely used in practice, because Express responses have a couple of convenient helper functions. If you're building a RESTful API or another backend service that sends responses in JSON, you should use the res.json() function. The res.json() function converts the given object to JSON using JSON.stringify() and sets the content type to 'application/json; charset=utf-8'.

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

app.get('*', function(req, res) {
  res.json({ answer: 42 });
});

const server = await app.listen(3000);

const response = await axios.get('http://localhost:3000');
response.data; // { answer: 42 }
response.headers['content-type']; // 'application/json; charset=utf-8'

Rendering Template Languages

Express supports several different popular templating languages. For example, you can use the Pug language (formerly known as Jade).

Given the below Pug code in views/test.pug:

h1= message

The below Express route handler will render an h1 tag that contains 'Hello, World'. You do not need to install any libraries other than pug or explicitly require() pug.

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

// Set 'pug' as the view engine
app.set('view engine', 'pug');

app.get('*', function(req, res) {
  // Loads `views/test.pug` and renders it with the given `locals`
  const locals = { message: 'Hello, World' };
  res.render('test', locals);
});

const server = await app.listen(3000);

const response = await axios.get('http://localhost:3000');
response.data; // '<h1>Hello, World</h1>'

Setting the Response Status

The res.status() function lets you set the response status. Unlike res.send(), res.json(), and res.render(), res.status() does not actually send the response. That's why you will usually see res.status().json() or res.status().render().

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

app.get('*', function(req, res) {
  // Sets the response status to 201 "Created". The response status
  // is 200 "OK" by default.
  res.status(201).json({ ok: 1 });
});

const server = await app.listen(3000);

const response = await axios.get('http://localhost:3000');
response.status; // 201

Response Headers

The res.status() function lets you set HTTP response headers. The below example demonstrates manually seting the response content type for sending an SVG image.

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

app.get('*', function(req, res) {
  // Setting content-type means Chrome will treat this endpoint as
  // an image to download rather than a page to display.    
  res.set('content-type', 'image/svg+xml').send(`
    <svg width="100" height="100">
      <circle cx="50" cy="50" r="40" stroke="blue" stroke-width="4" fill="white" />
    </svg>
  `);
});

const server = await app.listen(3000);

const response = await axios.get('http://localhost:3000');
response.headers['content-type']; // image/svg+xml; charset=utf-8

What Happens if You Don't Send a Response?

In Express, you're responsible for sending your response using res.json(), res.send(), res.end(), or res.render(). Otherwise the request will hang forever. Express will not throw any error if you don't send a response.

// Express won't throw an error, but any request to this endpoint will hang
// forever because there's no `res.send()`.
app.get('*', function(req, res) {
  res.status(201);
});

Want to become your team's Express expert? There's no better way to really grok a framework than to write your own clone from scratch. In 15 concise pages, this tutorial walks you through how to write a simplified clone of Express called Espresso. Get your copy!

Espresso supports:
  • Route handlers, like `app.get()` and `app.post()`
  • Express-compatible middleware, like `app.use(require('cors')())`
  • Express 4.0 style subrouters
As a bonus, Espresso also supports async functions, unlike Express.

Get the tutorial and master Express today!

Did you find this tutorial useful? Say thanks by starring our repo on GitHub!

More Express Tutorials