Read and parse POST/PATCH/PUT request JSON or form body with Express and no dependencies
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-parser is a dependency of Express and its main JSON parsing and url encoded body parsing functionality is exposed as express.json()
and express.urlencoded()
ie. middleware for parsing the most common request bodies is built into Express.
Note:
express.json
andexpress.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
Table of Contents
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):
Photo by Mahir Uysal
Get The Jest Handbook (100 pages)
Take your JavaScript testing to the next level by learning the ins and outs of Jest, the top JavaScript testing library.
orJoin 1000s of developers learning about Enterprise-grade Node.js & JavaScript