Read and parse POST/PATCH/PUT request JSON or form body with Express and no dependencies

Hugo Di Francesco - May 24 '19 - - Dev Community

When asked to handle data in a request body, developers who have used Express (the “Fast, unopinionated, minimalist web framework for Node.js”) before, reach for the body-parser library.

What they might not know is that body-parse is a dependency of Express and its main JSON parsing and url encoded body parsing functionality is exposed as express.json() and express.urlencoded(). A middleware for parsing JSON request bodies built-into Express.

Note: express.json and express.urlencoded exist in Express 4.16+

The global express.json() middleware is not to be confused with the res.json() function which sends back a body as JSON (and sets the content format headers to JSON).

The code for json bodies is at https://codesandbox.io/s/olrn6x3n19?fontsize=14, you can view the app at https://olrn6x3n19.sse.codesandbox.io/.

The code for URL encoded form bodies is at https://codesandbox.io/s/6njqzmyw4k?fontsize=14, you can test it out at https://6njqzmyw4k.sse.codesandbox.io/.

Real(ish) world usage in projects, you can also find more Express posts on Code with Hugo

Parsing JSON bodies

Drop-in example

Here is an example app that reflects the request POST body in the response:

const express = require('express')
const app = express()

app.use(express.json())
app.post(
  '/test',
  (req, res) => res.json(req.body)
)

const PORT = process.env.PORT || 3000
app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`)
})

You can see it running at https://olrn6x3n19.sse.codesandbox.io/, test it using:

curl --request POST \
  --url https://olrn6x3n19.sse.codesandbox.io/test \
  --header 'content-type: application/json' \
  --data '{
    "json-parsing": "just with Express",
    "no": "body-parser"
}'

It will output:

{"json-parsing":"just with Express","no":"body-parser"}

Which is exactly what we sent in the --data property of the curl request.

Extended configuration options

You can pass options into it like so (all the values are the default values for these options):

app.use(express.json({
  inflate: true,
  limit: '100kb',
  reviver: null,
  strict: true,
  type: 'application/json',
  verify: undefined
}))

The full API docs for express.json are at expressjs.com/en/api.html#express.json.

A run-through of the options follows.

inflate controls whether or not to handle compressed/deflated request bodies. When it’s set to false, compressed/deflated bodies will get rejected.

limit controls the maximum body size. It can be either a number of bytes or a string which is compatible with the bytes library.

strict is about locking JSON.parse down to just objects and arrays. If true, only JSON.stringify-ed objects and arrays will be allowed, if false, anything that JSON.parse accepts will be parsed.

type controls which content-type the middleware will attempt to parse. The value for this option can be a string, an array of strings, or a function. Content-type wildcards are supported to some extent since string(s) are passed to the type-is library.

verify is an optional function with verify(req, res, buf, encoding) signature. buf is a Buffer containing the raw request body. verify can be used to abort parsing by throwing an error.

Parsing URL encoded form bodies

In the same way we used express.json we can use express.urlencoded.

Drop-in example

We pass extended: false to avoid a warning.

const express = require('express')
const app = express()

app.use(express.urlencoded({ extended: false }))
app.post(
  '/test',
  (req, res) => res.json(req.body)
)

const PORT = process.env.PORT || 3000
app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`)
})

You can see it running at https://6njqzmyw4k.sse.codesandbox.io/, test it using the form on the page.

Extended configuration options

You can pass options into express.urlencoded like so (all the values are the default values for these options):

app.use(express.json({
  extended: true,
  inflate: true,
  limit: '100kb',
  parameterLimit: 1000,
  type: 'application/x-www-form-urlencoded',
  verify: undefined
}))

The full API docs for express.json are at expressjs.com/en/api.html#express.urlencoded.

A run-through of the options follows.

extended pretty much a toggle between the qs (when true) and querystring (when false) libraries. qs allows for rich objects and arrays to be encoded, querystring does not. Keep this as false for simple forms (all key-value pairs) and true when you’re sending arrays/maps of values.

inflate controls whether or not to handle compressed/deflated request bodies. When it’s set to false, compressed/deflated bodies will get rejected.

limit controls the maximum body size. It can be either a number of bytes or a string which is compatible with the bytes library.

parameterLimit controls the maximum number of fields that we’ll attempt to parse from the url encoded form body.

type controls which content-type the middleware will attempt to parse. The value for this option can be a string, an array of strings, or a function. Content-type wildcards are supported to some extent since string(s) are passed to the type-is library.

verify is an optional function with verify(req, res, buf, encoding) signature. buf is a Buffer containing the raw request body. verify can be used to abort parsing by throwing an error.

More about body-parser and other body-parsing libraries

This means we don’t need to install body-parser to load up most of our bodies. Express’ built-in JSON and URL encoded form body parsing covers the majority of use cases. What we might need a library for is multipart bodies, there are alternative libraries to handle that use-case (usually for file upload).

There are still some very specific cases where body-parser might still be necessary (see the docs at github.com/expressjs/body-parser):

unsplash-logo
Mahir Uysal

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .