Stop 05 · Express.js & Web FrameworksTopics · 4/14

Request & Response Objects

Part of the Backend Developer Roadmap

In short

Every handler gets two objects: req tells you everything about what came in, and res is your toolkit for replying. Knowing them well is half of backend work.

Express's `req` and `res` objects — carrying everything about the incoming request and providing the methods to shape your response (status, headers, body).

The mascot as a waiter reads an order slip while balancing a tray with food and a bill.

Think of it like this

The order slip and the tray

The waiter gets an order slip: table number, dishes, 'less spicy'. That's req. He comes back with a tray, the food and the bill. That's res. You read the slip carefully, then fill the tray correctly.

Watch it happen

What lives on req and res

req (incoming)

  • params, query, body
  • headers via req.get()
  • method, path, ip, cookies

res (outgoing)

  • status(code) sets the status
  • json(), send(), redirect()
  • set() headers, cookie()

Read from req, write to res. Never send more than one response per request.

The big ideas

What you need to know

Three places for input

req.params from the path, req.query from after the ?, req.body from the request body.

Headers

req.get("Authorization") reads a header. res.set("Cache-Control", "no-store") writes one.

Status codes tell the story

200 OK, 201 Created, 204 No Content, 400 bad input, 401 not logged in, 404 not found.

res methods chain

res.status(201).json(order) sets the status and sends in one line.

See it in code

Walk through the code

js
1app.put("/shops/:shopId/items/:itemId", (req, res) => {2  const { shopId, itemId } = req.params;     // from the path3  const { notify } = req.query;              // ?notify=true4  const { price } = req.body;                // JSON body5  const lang = req.get("Accept-Language");   // a header6 7  if (typeof price !== "number") {8    return res.status(400).json({ error: "price must be a number" });9  }10 11  res12    .status(200)13    .set("X-Updated-By", "inventory-api")14    .json({ shopId, itemId, price, notify: notify === "true", lang });15});

1/3Pull input from all four places: path params, query string, body and headers.

Query values are always strings. ?notify=true gives "true", not the boolean true, so compare it as a string.

Save yourself the pain

Common mistakes

Oops

Calling res.json() twice in one handler, getting 'Cannot set headers after they are sent'.

Do this instead

Use return when you respond early. Each request gets exactly one response.

Oops

Sending 200 with { error: "not found" } in the body.

Do this instead

Use the right status code, like 404. Clients and monitoring tools read the status first.

Your mission

Inspect a request

~15 min

Quick check

GET /search?page=2. What is typeof req.query.page?

Go deeper

  1. 1Log `req.params`, `req.query` and `req.body` for a single request to see the difference.
  2. 2Practice `res.status().json()` for consistent JSON API responses.
  3. 3Learn `res.redirect()`, `res.sendFile()` and other response helpers beyond JSON.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge