# Application, Request and Response

Course: [Express.js](https://www.devtutorials.ai/learn/expressjs) · Section: Requests and Routing
Source: https://www.devtutorials.ai/learn/expressjs/requests-routing/request-and-response

> The app object and its settings, app.locals and sub-apps, everything req holds, every way res can answer, the one-response rule, and caching with ETags, 304 answers and range requests.

## The Express Application

**Application object** = the object that `express()` returns. We always call it `app`.

- `app` holds your routes, middleware and settings.
- `app` is also a function. Node.js calls it for every request.
- `app.listen` starts a server that sends requests to `app`.
- One project usually has one main `app`.
- You can mount smaller apps inside it.

**Simple lesson:** `app` is the brain of your server. Everything starts from it.

### A Real-World Example

The canteen manager keeps a notice board in the kitchen.

1. "Opening time: 8 AM."
2. "Dark mode on the menu screen: off."
3. "School name: Green Valley."
4. Every cook reads the same board.

`app` has a notice board too. It is called **settings**, plus a shared shelf called **app.locals**.

In this lesson, you will learn:

1. What the application object holds and how settings work.
2. The two meanings of `app.get`, and `app.locals` vs `res.locals`.
3. How `NODE_ENV` changes error output, and how to mount a sub-app.
4. What `req` tells you: URL details, params, query, body and headers.
5. How `res` sends content, status codes and headers.
6. The one-response rule, ETags, 304 answers and ranges.

## Application Settings

- **app.set(name, value)** = saves a setting.
- **app.get(name)** = reads a setting.
- **app.enable(name)** = sets it to `true`.
- **app.disable(name)** = sets it to `false`.
- **app.enabled(name)** = asks "is it true?".
- **app.disabled(name)** = asks "is it false?".

- The terminal prints each setting when the server starts.
- `env` is `development` by default.
- Open **Headers**. There is no `X-Powered-By` header, because you disabled it.

**Simple lesson:** Settings are named values on `app`. Set them before your routes.

## The Two Meanings of app.get

`app.get` does two different jobs. The number of arguments decides which.

- **app.get(name)** with one argument = read a setting.
- **app.get(path, handler)** with two or more = add a GET route.
- `app.get("env")` returns `"development"`.
- `app.get("/env", handler)` answers requests to `/env`.
- Paths start with `/`. Setting names usually do not.

Easy way to remember: **a path starts with `/`.** `app.get("env")` reads, `app.get("/env", ...)` routes.

**Simple lesson:** One argument reads a setting. A path and a function make a route.

## Sharing Data with app.locals

**app.locals** = an object for values the whole app shares.

- Set it once: `app.locals.school = "Green Valley"`.
- Read it in any route: `req.app.locals.school`.
- Views (templates) can read it directly. See **Views and Static Files**.
- **res.locals** is different. It lives for one request only.
- Use `app.locals` for things that never change per request, like the school name.

- Send `/about` twice. `school` stays the same.
- `askedAt` changes each time, because `res.locals` is new for every request.

**Simple lesson:** `app.locals` is for the whole app. `res.locals` is for one request.

## The Environment Setting

**env** = a setting that says where the app is running.

- Express copies it from the `NODE_ENV` environment variable.
- If `NODE_ENV` is missing, `env` is `development`.
- Real servers set `NODE_ENV=production`.
- In production, Express hides error details from visitors.
- In development, Express shows the full error to help you.

- Send `/broken`. The visitor only sees "Internal Server Error".
- The real message still prints in the terminal, for you.
- Change `.env` to `NODE_ENV=development` and run again. Now the visitor sees the message too.

Always set `NODE_ENV=production` on real servers. Error details can leak passwords and file paths.

**Simple lesson:** `env` changes how much Express tells visitors when things break.

## Useful Built-In Settings

- **x-powered-by:** adds `X-Powered-By: Express`. Turn it off to hide what you use.
- **json spaces:** pretty-prints JSON, such as `app.set("json spaces", 2)`.
- **case sensitive routing:** makes `/Menu` and `/menu` different.
- **strict routing:** makes `/menu` and `/menu/` different.
- **query parser:** `"simple"` by default in Express 5. `"extended"` allows nested objects.
- **trust proxy:** for apps behind a proxy. See **Redirects, Content Negotiation and Proxies**.
- **view engine** and **views:** for HTML templates. See **Views and Static Files**.

- With curl or a browser, the JSON now comes on many lines. The lab panel always formats JSON, so look at `Content-Length` under **Headers**: it grew.
- `/Menu` gives 404, because routing is now case sensitive.
- Remove the `enable` line and run again. `/Menu` works.

**Simple lesson:** A few settings change how every route behaves.

## Mounting a Sub-Application

**Sub-application** = a second `express()` app used inside the main one.

- Create it like any app: `const admin = express()`.
- Mount it with `app.use("/admin", admin)`.
- Its routes now live under `/admin`.
- **admin.mountpath** = the path it was mounted on.
- The **mount** event fires when it is mounted.
- The sub-app keeps its own settings.

- The terminal prints the mount message before the server starts.
- `admin.get("/")` answers `/admin`, because of the mount path.
- Most projects use **Routing and Routers** for this instead. It is lighter.

A sub-app is a full Express app with its own settings. If you only need to group routes, a router is lighter. See **Routing and Routers**.

**Simple lesson:** `app.use(path, otherApp)` plugs one app into another.

## Request and Response Objects

Every route handler gets two objects: `req` and `res`.

- **req** = the request object. It holds everything the client sent.
- **res** = the response object. It has tools to send your answer.
- Express builds both from the Node.js request and response.
- Express adds many helpers on top, such as `req.query` and `res.json`.
- You read from `req`. You write with `res`.

**Simple lesson:** `req` is the question. `res` is how you answer.

### A Second Example

A canteen order slip arrives at the kitchen.

1. The slip says who ordered, what they want and how many.
2. The cook reads the slip.
3. The cook fills a plate and adds a label.
4. The plate goes back to the counter.

The slip is `req`. The plate and its label are `res`.

## Request URL Information

- **req.method** = the HTTP method, such as `GET`.
- **req.url** = the path and query, as seen by the current router.
- **req.originalUrl** = the full original path and query. It never changes.
- **req.baseUrl** = the path where the current router is mounted.
- **req.path** = the path without the query string.
- **req.route** = the route that matched, including its path pattern.

- `originalUrl` keeps the full text: `/canteen/menu/7?veg=true`.
- `baseUrl` is `/canteen`, where the router is mounted.
- `url` and `path` are what the router itself sees.

Easy way to remember: **path for routing, originalUrl for logs, baseUrl for where the router lives.**

**Simple lesson:** Use `req.path` to know where. Use `req.originalUrl` for logs.

## Request Data

- **req.params** = values from the path, such as `:id`. See **Routing and Routers**.
- **req.query** = values after `?`, such as `?veg=true`.
- **req.body** = data sent in the body. It needs a body parser. See **Body Parsers and Third-Party Middleware**.
- **req.headers** = every header, with lowercase names.
- **req.get(name)** = one header, in any letter case.
- **req.header(name)** = the same as `req.get`. It is just another name.
- **req.cookies** = cookies, only after you add cookie-parser. See **Cookies and Sessions**.

- Every value from the URL is a **string**. `"7"` is not the number `7`.
- `req.get` ignores letter case. `X-Student-Id` and `x-student-id` are the same.
- In Express 5, `req.body` is `undefined` when no body was parsed.

Treat everything in `req` as untrusted. Any client can send any params, query, body or headers. Check values before you use them.

**Simple lesson:** params come from the path, query from after the `?`, body from the message.

## Request Connection Information

- **req.protocol** = `http` or `https`.
- **req.secure** = `true` when the protocol is `https`.
- **req.hostname** = the host name without the port, such as `localhost`.
- **req.ip** = the client's IP address.
- **req.ips** = a list of IP addresses when the app is behind a proxy.
- **req.subdomains** = parts before the main domain, such as `["menu"]` for `menu.school.in`.
- **req.xhr** = `true` when the `X-Requested-With` header is `XMLHttpRequest`.

### Request Type Checks

- **req.is(type)** = checks the `Content-Type` of the body.
- `req.is("json")` returns `"json"` when the body is JSON, and `false` otherwise.
- **req.fresh** and **req.stale** = whether the client's cached copy is still good.
- **req.range()** = reads the `Range` header, used for partial downloads.

- `ip` is `::1`, the IPv6 address of your own computer.
- Behind a proxy, these values need the `trust proxy` setting.

**Simple lesson:** `req` also knows how the client connected.

## Sending Content with res

- **res.send(body)** = sends text, HTML, an object or an array.
- **res.json(data)** = always sends JSON.
- **res.end()** = ends the response with no Express helpers. Rarely needed.
- **res.sendStatus(code)** = sends a status code and its standard text.
- **res.jsonp(data)** = old-style JSON for script tags. Rarely used today.

- `res.sendStatus(204)` sends "No Content" with an empty body.
- `res.sendStatus(404)` would send the text "Not Found".
- `res.end()` sends nothing at all, with status 200.

**Simple lesson:** Use `res.json` for data and `res.send` for text and HTML.

## Status and Headers

- **res.status(code)** = sets the status. Chain it: `res.status(201).json(order)`.
- **res.set(name, value)** = sets a header. `res.header` is the same.
- **res.append(name, value)** = adds another value to a header.
- **res.get(name)** = reads a header you already set.
- **res.type(type)** = sets `Content-Type` from a short name like `"json"`.
- **res.vary(header)** = tells caches the answer depends on that header.
- **res.links(links)** = sets the `Link` header, used for page links.

- Open **Headers** to see each one.
- `X-Note` holds both values: `fresh, hot`.
- Set headers **before** you send. After sending, it is too late.

**Simple lesson:** Status and headers first, then the body.

## Response Locals

**res.locals** = an object that lives for one request only.

- Middleware can put values in it.
- Later middleware and the route handler can read them.
- Views can read them too. See **Views and Static Files**.
- It is the safe place for per-request data, such as the logged-in user.

**Simple lesson:** Pass data down the chain with `res.locals`.

## The One-Response Rule

Each request gets exactly one response.

- Send twice, and Node.js throws `ERR_HTTP_HEADERS_SENT`.
- This usually happens when code keeps running after an early `res.send`.
- Fix it with `return res.send(...)`.
- **res.headersSent** = `true` once the response has started.

- Send `/greet` with no name. The client gets 400, but the terminal shows an error.
- Add `return` before `res.status(400)` and run again.
- Now the error is gone, because the function stops early.

Easy way to remember: **return res.send(...)** whenever there is code below it.

**Simple lesson:** One request, one response. Use `return` to stop early.

## Caching and Partial Requests

Browsers try not to download the same thing twice.

- **ETag** = a short fingerprint of a response body. Express adds one to `res.send` answers.
- The browser keeps the copy and sends **If-None-Match** with that ETag next time.
- **req.fresh** = `true` when the client's copy still matches. **req.stale** is the opposite.
- When the copy is fresh, `res.send` answers **304 Not Modified** with no body. That saves data.
- **Range** = a header asking for only part of a file, such as `bytes=0-99`. Video players use it.
- **req.range(size)** reads it. It returns a list of `{ start, end }`, or `-1` when the range cannot be served.

- Send `/menu`, open **Headers** and copy the `ETag` value.
- Type it into the request headers as `If-None-Match: <the ETag>` and send again. You get **304** and an empty body.
- The range request gets **206 Partial Content** with only the first 20 characters.
- A range past the end gets **416 Range Not Satisfiable**.

**Simple lesson:** ETags let browsers reuse copies. Ranges let them download just a part.

## Common mistakes

<div className="tscroll">

| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
| `app.get("env")` to make a route | It adds a route called env | One argument reads a setting | No route is added |
| Setting `json spaces` after routes run | Order does not matter | Set settings before routes | Some routes miss the setting |
| Storing per-user data in `app.locals` | It is per request | It is shared by everyone | Users see each other's data |
| No `NODE_ENV` on the real server | Express guesses production | It defaults to development | Visitors see error details |
| Leaving `x-powered-by` on | It is harmless | It tells attackers what you use | Easier targeted attacks |
| `req.params.id + 1` | Params are numbers | Params are strings | `"7" + 1` gives `"71"` |
| Reading `req.body` without a parser | Express parses bodies by itself | Add `express.json()` first | `req.body` is `undefined` |
| Sending without `return` | Sending stops the function | The function keeps running | `ERR_HTTP_HEADERS_SENT` |
| Setting a header after sending | Headers can change any time | Headers go out first | Error, or the header is lost |
| Trusting `req.query.role` | Clients send only honest data | Anyone can type any URL | Users give themselves admin rights |
| `req.headers["X-Id"]` | Header names keep their case | `req.headers` uses lowercase names | `undefined`. Use `req.get("X-Id")` |

</div>

## Check Yourself

## Exercises

## What to Remember

- `express()` returns the application object, `app`.
- `app.set`, `app.get(name)`, `app.enable` and `app.disable` manage settings.
- `app.get(name)` reads a setting. `app.get(path, handler)` adds a route.
- `app.locals` is shared by the whole app. `res.locals` is per request.
- `NODE_ENV=production` hides error details from visitors.
- `req` holds the method, URL, params, query, body, headers and connection details.
- `res.send`, `res.json` and `res.sendStatus` send the answer.
- `res.status` and `res.set` must come before the body.
- Send exactly one response, and `return` when you stop early.

Next: **Routing and Routers**. You will learn route paths, parameters, query strings and the Express 5 path syntax.
