The Response Object

`res.send`, `res.json`, `res.status`, `res.redirect`

The Response Object

Everything you need to reply to a request — status codes, headers, bodies, redirects.

3 min read Level 1/5 #express#response#http
What you'll learn
  • Use res.send and res.json correctly
  • Set status codes and headers
  • Redirect and stream

res is the toolkit for replying. Here are the methods you’ll use every day.

res.send() — Most Things

res.send("Hello");                // text/html
res.send({ name: "Ada" });        // JSON (sets Content-Type)
res.send(Buffer.from("..."));     // binary
res.send([1, 2, 3]);              // JSON array

send picks the right Content-Type for you. Convenient — but when you specifically want JSON, prefer res.json():

res.json() — Explicit JSON

res.json({ id: 1, name: "Ada" });

Always sets Content-Type: application/json. Use this for API endpoints — clearer intent than send.

res.status() — Status Codes

Chainable:

res.status(201).json({ id: 1 });
res.status(204).end();
res.status(404).json({ error: "not found" });

Common ones:

CodeMeaning
200OK (default)
201Created
204No Content
301 / 302Redirect
400Bad Request
401Unauthorized
403Forbidden
404Not Found
409Conflict
422Unprocessable Entity
500Internal Server Error

res.set() — Headers

res.set("Cache-Control", "max-age=60");
res.set("X-Request-Id", reqId);
res.set({
  "Content-Type": "text/plain",
  "X-Powered-By": "my-api",
});

res.redirect() — Redirects

res.redirect("/login");                // 302
res.redirect(301, "/new-permanent");   // 301
res.redirect(303, "/check-email");     // 303

res.cookie() and res.clearCookie()

res.cookie("session", token, {
  httpOnly: true,
  secure:   true,
  sameSite: "lax",
  maxAge:   24 * 60 * 60 * 1000,
});

res.clearCookie("session");

res.sendFile() — Stream a File

import path from "node:path";

res.sendFile(path.resolve("./reports/q3.pdf"));

Streams the file with the right Content-Type and Content-Length. Good for downloads.

res.download() — Force Download

res.download("./reports/q3.pdf", "Q3-Report.pdf");

Sets Content-Disposition: attachment so the browser saves rather than displays.

Don’t res.end() Twice

Once a response is sent, you can’t add to it. Calling another res.* method after res.json(...) throws. Always return after sending:

if (!user) {
  return res.status(404).json({ error: "not found" });
}
res.json(user);
Serving Static Files →