Built-in middleware
The request body is the data a client sends along with POST, PUT or PATCH: form fields or JSON. Express does not read it by itself, so as not to waste time on requests that do not need a body. Express has ready middleware for parsing built in — nothing to install.
Built-in middleware
| Function | What it parses | Content-Type header |
|---|---|---|
express.json() | JSON | application/json |
express.urlencoded() | HTML form data | application/x-www-form-urlencoded |
express.text() | Plain text | text/plain |
express.static() | Does not parse, serves files from a folder | — |
Each function looks at the Content-Type header and parses only its own format. The result goes into req.body.
JSON
Enable JSON parsing at the top of src/app.js:
// src/app.js
app.use(express.json());
app.post('/api/posts', (req, res) => {
res.status(201).json({ received: req.body });
});Send a request from the terminal:
curl -X POST http://localhost:3000/api/posts -H "Content-Type: application/json" -d '{"title":"New post"}'The server returns {"received":{"title":"New post"}}: the body has been parsed into an ordinary object. If the JSON is malformed, Express answers with code 400 by itself.
Form data
An ordinary HTML form sends data in a different format — as a string title=...&body=.... It needs a second middleware:
// src/app.js
app.use(express.urlencoded());
app.post('/posts', (req, res) => {
res.send(`Title: ${req.body.title}`);
});Now a form with a field name="title" and method="post" passes the value into req.body.title. Forms are covered in detail in the chapter about pages.
Size limit
By default a body can be up to 100 KB — a bigger request gets a 413 response. The limit is changed with the limit option:
// src/app.js
app.use(express.json({ limit: '1mb' }));Do not raise it without need: a big limit lets a single client send the server megabytes of junk.
Where to add them
Both middleware are usually added as a pair at the top of src/app.js, before any routes:
// src/app.js
const app = express();
app.use(express.json());
app.use(express.urlencoded());
app.use('/posts', postsRouter);Common mistake
If the client did not send the Content-Type: application/json header, express.json() skips the body and req.body stays undefined. In Express 5 this is the default value, so req.body.title crashes with Cannot read properties of undefined. Always set the header in curl and fetch(), and read fields carefully in the handler: req.body?.title.