Working with Request Body Parsing

1. Using express.json() Middleware

OptionDefaultPurpose
limit100kbMax body size (string or bytes)
stricttrueOnly accept arrays/objects
typeapplication/jsonMIME types to parse
verify(req, res, buf, enc) => {}
reviverJSON.parse reviver fn
inflatetrueDecompress 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

Example: Form parser

app.use(express.urlencoded({ extended: true, limit: "10kb" }));

app.post("/contact", (req, res) => {
  const { name, email, message } = req.body;
  res.json({ ok: true });
});
OptionDefaultPurpose
extendedtruetrue=qs (nested), false=querystring (flat)
limit100kbMax body size
parameterLimit1000Max params (DoS protection)

3. Parsing URL-Encoded Data

Bodyextended:falseextended: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

TypeRecommended limit
JSON API100kb–1mb
Form submission10kb–100kb
File uploadUse multer (don't use json/urlencoded)
Webhooks1mb–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.typeHTTP status
entity.parse.failed400
entity.too.large413
encoding.unsupported415
request.aborted400

6. Using body-parser Package

StatusDetail
Built-in since Express 4.16express.json(), express.urlencoded(), etc. wrap body-parser
External installOnly 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) })
);
OptionPurpose
defaultCharsetDefault utf-8
typeMIME type filter

9. Setting Content-Type for Parsing

PatternMatches
"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.