Send a JSON response using Express
By Flavio Copes
Learn how to send a JSON response in Express using the Response.json() method, which takes an object or array and converts it to JSON before sending it.
To send a JSON response in Express, call res.json() in your route handler, passing an object or array. Express serializes it and sends it to the client.
When you listen for connections on a route in Express, the callback function will be invoked on every network call with a Request object instance and a Response object instance.
Example:
app.get('/', (req, res) => res.send('Hello World!'))
Here we used the Response.send() method, which accepts any string.
You can send JSON to the client by using Response.json(), a useful method.
It accepts an object or array, and converts it to JSON before sending it (if you want to inspect or validate the JSON your API returns, try my JSON formatter):
app.get('/user', (req, res) => {
res.json({ username: 'Flavio' })
})
The client receives this body:
{"username":"Flavio"}
res.json() also sets the Content-Type header to application/json, so the client knows to parse the response as JSON. With res.send() and a string you’d get text/html instead.
How do you set the status code?
Chain res.status() before it:
app.get('/user/:id', async (req, res) => {
const user = await findUser(req.params.id)
if (!user) {
return res.status(404).json({ error: 'User not found' })
}
res.json(user)
})
Without an explicit status, Express sends 200.
Be careful not to respond twice
Each request gets one response. If you call res.json() and the code keeps going until it hits another res.json() call, Express throws:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
This usually happens when you forget a return after handling an error case, like the 404 above. The return stops the function there, so the second res.json(user) never runs. Add it and the error goes away.
One more thing. res.send() can also take an object, and in that case it sends JSON too, by calling res.json() under the hood. Both work. I use res.json() because it tells whoever reads the code exactly what the endpoint returns.