Working with Request Body Parsing
1. Using express.json() Middleware
| Option | Default | Purpose |
limit | 100kb | Max body size (string or bytes) |
strict | true | Only accept arrays/objects |
type | application/json | MIME types to parse |
verify | — | (req, res, buf, enc) => {} |
reviver | — | JSON.parse reviver fn |
inflate | true | Decompress gzip/deflate bodies |
Example: JSON parser with raw access
app.use(express.json({
limit: "1mb",
verify: (req, res, buf) => { req.rawBody = buf; } // for HMAC verification
}));
2. Using express.urlencoded() Middleware
app.use(express.urlencoded({ extended: true, limit: "10kb" }));
app.post("/contact", (req, res) => {
const { name, email, message } = req.body;
res.json({ ok: true });
});
| Option | Default | Purpose |
extended | true | true=qs (nested), false=querystring (flat) |
limit | 100kb | Max body size |
parameterLimit | 1000 | Max params (DoS protection) |
3. Parsing URL-Encoded Data
| Body | extended:false | extended:true |
a=1&b=2 | {a:"1",b:"2"} | {a:"1",b:"2"} |
user[name]=Bob | {"user[name]":"Bob"} | {user:{name:"Bob"}} |
tags[]=a&tags[]=b | {tags:["a","b"]} | {tags:["a","b"]} |
4. Configuring Body Size Limits
| Type | Recommended limit |
| JSON API | 100kb–1mb |
| Form submission | 10kb–100kb |
| File upload | Use multer (don't use json/urlencoded) |
| Webhooks | 1mb–5mb (signed payloads) |
Warning: Setting limit too high enables DoS via memory exhaustion. Tune per route if needed.
5. Handling Parsing Errors
Example: Catch SyntaxError
app.use((err, req, res, next) => {
if (err.type === "entity.parse.failed") {
return res.status(400).json({ error: "Invalid JSON" });
}
if (err.type === "entity.too.large") {
return res.status(413).json({ error: "Payload too large" });
}
next(err);
});
| err.type | HTTP status |
entity.parse.failed | 400 |
entity.too.large | 413 |
encoding.unsupported | 415 |
request.aborted | 400 |
6. Using body-parser Package
| Status | Detail |
| Built-in since Express 4.16 | express.json(), express.urlencoded(), etc. wrap body-parser |
| External install | Only needed for older Express or custom config |
Example: Standalone body-parser (legacy)
import bodyParser from "body-parser";
app.use(bodyParser.json({ limit: "1mb" }));
app.use(bodyParser.urlencoded({ extended: true }));
7. Parsing Raw Body
Example: Stripe webhook signature
app.post("/webhooks/stripe",
express.raw({ type: "application/json" }),
(req, res) => {
const sig = req.headers["stripe-signature"];
const event = stripe.webhooks.constructEvent(req.body, sig, env.STRIPE_SECRET);
// req.body is a Buffer here
res.json({ received: true });
}
);
8. Parsing Text Body
Example: Plain text input
app.use("/api/markdown",
express.text({ type: "text/markdown", limit: "200kb" }),
(req, res) => res.json({ html: marked(req.body) })
);
| Option | Purpose |
defaultCharset | Default utf-8 |
type | MIME type filter |
9. Setting Content-Type for Parsing
| Pattern | Matches |
"application/json" | Exact |
"*/json" | Any subtype +json |
"application/*+json" | JSON variants (e.g., application/vnd.api+json) |
| Function | (req) => req.headers["content-type"] === "..." |
10. Verifying Parsed Body
Example: Capture raw body for HMAC
app.use(express.json({
verify: (req, res, buf, encoding) => {
const signature = req.headers["x-signature"];
const expected = crypto.createHmac("sha256", env.SECRET).update(buf).digest("hex");
if (signature !== expected) throw Object.assign(new Error("Bad signature"), { status: 401 });
}
}));
Note: Throwing in verify aborts the request before the JSON is parsed — perfect for webhook signature checks.