# Body Parsers and Third-Party Middleware

Course: [Express.js](https://www.devtutorials.ai/learn/expressjs) · Section: Express Middleware
Source: https://www.devtutorials.ai/learn/expressjs/middleware/body-parsers

> express.json and its options, handling invalid JSON, express.urlencoded for forms, express.text and express.raw for webhooks, body size limits, and how to choose, install, configure and place third-party middleware.

## Body Parsers Introduction

A request body arrives as plain text. Your code wants a JavaScript object.

- **Body parser** = middleware that reads the body and puts the result in `req.body`.
- Express 5 has four built in: `express.json()`, `express.urlencoded()`, `express.text()` and `express.raw()`.
- Each parser only reads bodies with a matching `Content-Type`.
- Without a parser, `req.body` is `undefined` in Express 5.
- **Third-party middleware** = packages from npm that add more features.

**Simple lesson:** A body parser turns the raw body into `req.body`.

### A Real-World Example

The canteen gets orders in different forms.

1. Some come as typed slips in a fixed format.
2. Some come as ticks on a printed form.
3. Some come as a plain note.
4. A helper at the counter reads each kind and writes it neatly for the cook.

The helpers are the parsers. The neat note is `req.body`.

In this lesson, you will learn:

1. How `express.json()` works and its options.
2. How to handle invalid JSON.
3. How to read HTML form data with `express.urlencoded()`.
4. When to use `express.text()` and `express.raw()`.
5. How to set size limits.
6. How to choose, install and place third-party middleware.

## Reading JSON with express.json()

- Add it once: `app.use(express.json())`.
- It reads bodies with `Content-Type: application/json`.
- The result lands in `req.body` as an object or array.
- Other content types are skipped, and `req.body` stays `undefined`.
- Register it **before** the routes that read `req.body`.

- The first request is JSON, so `req.body` holds the order.
- The second says `text/plain`, so the JSON parser skips it.
- Edit the body in the client panel and press **Send** to try your own.

**Simple lesson:** `express.json()` fills `req.body`, but only for JSON requests.

## express.json() Options

- **limit:** the largest body allowed. Default `"100kb"`.
- **strict:** only accept objects and arrays. Default `true`.
- **type:** which content types to parse. Default `"application/json"`.
- **reviver:** a function that changes values while parsing.
- **inflate:** accept gzip-compressed bodies. Default `true`.
- **verify:** a function that checks the raw body before parsing.

**Simple lesson:** The defaults are safe. Change `limit` when you need to.

## Handling Invalid JSON

- A broken body like `{item: Dosa` cannot be parsed.
- The parser calls `next(err)` with status **400**.
- `err.type` is `"entity.parse.failed"`.
- Without your own error handler, the client gets an HTML error page.
- An API should answer with clear JSON instead.

- The first request gets a clear 400 JSON message.
- Remove the error middleware and run again. Now it is an HTML page.

Easy way to remember: **`err.type` tells you what broke.** `entity.parse.failed` is bad JSON, `entity.too.large` is a big body.

**Simple lesson:** Catch parser errors and answer in the same format as your API.

## Reading Form Data with express.urlencoded()

A normal HTML `<form method="post">` sends `application/x-www-form-urlencoded`.

- The body looks like `name=Priya&item=Idli&qty=2`.
- `express.urlencoded()` turns it into `{ name: "Priya", item: "Idli", qty: "2" }`.
- Every value is a **string**.
- Repeated names, like two checkboxes, become an **array**.
- **extended: false** (the Express 5 default) keeps it flat.
- **extended: true** allows nested names like `address[city]=Chennai`.

- `likes` becomes `["idli", "vada"]`.
- `rating` is the string `"5"`, not a number.
- With `extended: true`, `address` becomes a nested object.

**Simple lesson:** Forms arrive as strings. Convert and check them before use.

## Text and Raw Bodies

- **express.text()** = puts the body in `req.body` as a string. For `text/plain`.
- **express.raw()** = puts the exact bytes in `req.body` as a Buffer. For `application/octet-stream`.
- Use `type` to choose other content types: `express.raw({ type: "application/json" })`.
- **Webhooks** often need the raw body. Payment and chat services sign the exact bytes they send.
- If `express.json()` runs first, the exact bytes are gone. Put `express.raw()` on the webhook route only.

Real webhook checks use `node:crypto`: they compute an HMAC of the raw body with a shared secret and compare it to the signature header. This lab compares a fixed text, because the idea is the same: check the exact bytes before trusting them.

**Simple lesson:** Use `text()` for plain notes and `raw()` when the exact bytes matter.

## Size Limits

Large bodies can slow down or crash your server.

- Every parser has a **limit**. The default is `100kb`.
- A bigger body gets **413 Payload Too Large**.
- Set a smaller limit when you expect small bodies: `express.json({ limit: "1kb" })`.
- **parameterLimit** caps how many form fields `urlencoded` accepts. Default 1000.
- The parser checks the `Content-Type` first. A wrong type is simply skipped.

- The small order passes. The long one gets 413.

**Simple lesson:** Set limits that match what your routes really need.

## Third-Party Middleware

**Third-party middleware** = middleware from npm, written by other developers.

- **helmet:** sets safe HTTP headers. See **Express Security**.
- **cors:** lets web pages from other origins call your API.
- **morgan:** logs every request. See **Logging and Debugging**.
- **compression:** compresses responses so they download faster.
- **cookie-parser:** reads cookies. See **Cookies and Sessions**.
- **multer:** reads file uploads. See **File Handling**.

### Install, Import, Configure

```bash
npm install compression
```

```js
import express from "express";
import compression from "compression";

const app = express();

// Configure: only compress responses bigger than 1 KB.
app.use(compression({ threshold: 1024 }));

app.get("/menu", (req, res) => {
  res.json(bigMenu);
});
```

- Install it with npm. It appears in `package.json`.
- Import it, call it to get the middleware, and pass it to `app.use`.
- Most packages take an options object, like `{ threshold: 1024 }`.

In this course's labs, only `express`, `dotenv` and `ejs` are installed. Third-party examples are shown as code to copy into your own project.

### Choosing a Package

- **Maintained:** recent releases and answered issues.
- **Safe history:** check `npm audit` and the package's security notes.
- **Works with Express 5 and your Node.js version:** read the README.
- **Small:** fewer dependencies means less to go wrong.
- **Needed:** if five lines of your own code do the job, skip the package.

### Where to Put It

- Read the package docs. Some must come first, like `helmet`.
- Put it before the routes that depend on it.
- Some need another middleware first, like sessions needing cookies.

**Simple lesson:** Install, import, call with options, then `app.use` it in the right place.

## Common mistakes

<div className="tscroll">

| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
| No `express.json()` | Express reads JSON by itself | Add the parser | `req.body` is `undefined` |
| Client sends no `Content-Type` | The parser guesses JSON | It only reads matching types | `req.body` is `undefined` |
| Form values used as numbers | `"5"` is 5 | Form values are strings | Wrong totals and comparisons |
| `express.json()` before a webhook route | The parsed body is good enough | Signatures need the exact bytes | Valid webhooks are rejected |
| Raising `limit` to `"50mb"` everywhere | Bigger is friendlier | Keep limits small by default | Easy to overload the server |
| `app.use(compression)` | Pass the package itself | Call it: `compression()` | Requests hang or break |

</div>

## Check Yourself

## Exercises

## What to Remember

- Body parsers fill `req.body`. Without one, it is `undefined`.
- `express.json()` for JSON, `express.urlencoded()` for forms.
- `express.text()` for plain text, `express.raw()` when exact bytes matter.
- Catch `entity.parse.failed` and `entity.too.large` and answer clearly.
- Keep body limits small.
- Third-party middleware: install, import, call with options, `app.use` in the right place.

Next: **Views and Static Files**. You will build HTML pages from data with EJS templates.
