# res.json() vs res.send() vs res.end() in Express

Source: https://tpiros.dev/blog/res-json-vs-res-send-vs-res-end-in-express

Express is one of the most popular web frameworks for Node.js. Most Node.js developers have used it at some point. It's got a pile of HTTP utility methods, and it performs well.

When you work with Express, you get access to a request and a response object. The response object gives you several ways to send data back: `res.json()`, `res.send()`, and `res.end()`. The question that keeps coming up: how are these different? Let's walk through them.

# Response

Whenever an Express app receives an HTTP request, it hands the developer an object commonly called `res`. Here's a bare-bones example:

```javascript
app.get('/api/test', (req, res) => {
  // ... do something ...
});
```

The `res` object is an enhanced version of Node.js's native response object.

## Sending a response

There are multiple ways to send responses with Express. Let's go through them.

### `res.send()`

Call `res.send()` to send a response. Its signature looks like this: `res.send([body])`, where the body can be a `Buffer`, `String`, `Object`, or `Array`.

This method sets the `Content-Type` response header automatically based on what you pass in. Hand it a `Buffer` and the `Content-Type` becomes `application/octet-stream` (unless you've set it to something else manually).

> You can set the `Content-Type` header yourself via `res.set('Content-Type', 'text/html');`.

Many developers use Express to build RESTful APIs, and most of those APIs return JSON. So the question surfaces: should you use `res.send()` to return JSON data (since it accepts objects), or should you use `res.json()`?

Let's see what happens when we send JSON data:

```javascript
app.get('/api/test', (req, res) => {
  res.send({ hello: 'world' });
});
```

The response header:

```
  X-Powered-By: Express
  Content-Type: application/json; charset=utf-8
  Content-Length: 17
  ETag: W/"11-IkjuL6CqqtmReFMfkkvwC0sKj04"
  Date: Fri, 10 Aug 2018 09:34:13 GMT
  Connection: keep-alive
```

Express correctly sets the `Content-Type`. So if that works, why does `res.json()` exist at all?

### `res.json()`

`res.json()` has extra functionality tied specifically to JSON. It can format the returned data using two options:

```javascript
app.set('json replacer', replacer); // property transformation rules
app.set('json spaces', 2); // number of spaces for indentation
```

These options get passed to `JSON.stringify()`, whose signature is: `JSON.stringify(object, replacer, space)`. After calling `JSON.stringify()`, `res.json()` then calls `res.send()` under the hood.

Last, let's look at `res.end()`.

> Take a look at this article to see what happens when you don't call `res.end()`: [Concurrent HTTP connections in Node.js](https://fullstack-developer.academy/concurrent-http-connections-in-node-js/)

### `res.end()`

This method ends the response. But do you always need it? The answer: sometimes yes, sometimes no.

You'd use `res.end()` when you want to end the response **without** sending any data. A 404 page, for example:

```javascript
res.status(404).end();
```

Here we set the HTTP status code explicitly and close the response right after.

But if you want to send data **and** end the response? Both `res.send()` and `res.json()` handle that for you. They send the data and close the response, so there's no need to call `res.end()` separately.

> `res.end()` doesn't send an ETag header with the HTTP response, while `res.send()` does. That Entity Tag header matters for web cache validation. It helps caches work more efficiently and saves bandwidth.

# Conclusion

To sum it up: `res.json()` gives you extra JSON formatting options. If you don't need those, `res.send()` works perfectly fine for returning response objects. Both methods also close the response for you. No extra steps needed.
