Note: If you decide to specify your own content type with the Content-Type
header, UTF-8 will not be the default. Be sure to include UTF-8 like this text/html; charset=utf-8
.
As with the other APIs, addContentTypeParser
is encapsulated in the scope in which it is declared. This means that if you declare it in the root scope it will be available everywhere, while if you declare it inside a plugin it will be available only in that scope and its children.
Fastify automatically adds the parsed request payload to the object which you can access with request.body
.
Fastify first tries to match a content-type parser with a string
value before trying to find a matching RegExp
. If you provide overlapping content types, Fastify tries to find a matching content type by starting with the last one passed and ending with the first one. So if you want to specify a general content type more precisely, first specify the general content type and then the more specific one, like in the example below.
// Here only the second content type parser is called because its value also matches the first one
fastify.addContentTypeParser('application/vnd.custom+xml', (request, body, done) => {} )
fastify.addContentTypeParser('application/vnd.custom', (request, body, done) => {} )
// Here the desired behavior is achieved because fastify first tries to match the `application/vnd.custom+xml` content type parser
fastify.addContentTypeParser('application/vnd.custom', (request, body, done) => {} )
fastify.addContentTypeParser('application/vnd.custom+xml', (request, body, done) => {} )
Besides the addContentTypeParser
API there are further APIs that can be used. These are hasContentTypeParser
, removeContentTypeParser
and removeAllContentTypeParsers
.
hasContentTypeParser
if (!fastify.hasContentTypeParser('application/jsoff')){
fastify.addContentTypeParser('application/jsoff', function (request, payload, done) {
jsoffParser(payload, function (err, body) {
})
}
removeContentTypeParser
With removeContentTypeParser
a single or an array of content types can be removed. The method supports string
and RegExp
content types.
removeAllContentTypeParsers
In the example from just above, it is noticeable that we need to specify each content type that we want to remove. To solve this problem Fastify provides the removeAllContentTypeParsers
API. This can be used to remove all currently existing content type parsers. In the example below we achieve exactly the same as in the example above except that we do not need to specify each content type to delete. Just like removeContentTypeParser
, this API supports encapsulation. The API is especially useful if you want to register a that should be executed for every content type and the built-in parsers should be ignored as well.
fastiy.removeAllContentTypeParsers()
fastify.addContentTypeParser('text/xml', function (request, payload, done) {
xmlParser(payload, function (err, body) {
done(err, body)
})
})
Notice: The old syntaxes function(req, done)
and async function(req)
for the parser are still supported but they are deprecated.
Body Parser
You can parse the body of a request in two ways. The first one is shown above: you add a custom content type parser and handle the request stream. In the second one, you should pass a parseAs
option to the addContentTypeParser
API, where you declare how you want to get the body. It could be of type 'string'
or 'buffer'
. If you use the parseAs
option, Fastify will internally handle the stream and perform some checks, such as the of the body and the content length. If the limit is exceeded the custom parser will not be invoked.
fastify.addContentTypeParser('application/json', { parseAs: 'string' }, function (req, body, done) {
try {
var json = JSON.parse(body)
done(null, json)
} catch (err) {
err.statusCode = 400
})
See example/parser.js
for an example.
Custom Parser Options
parseAs
(string): Either'string'
or'buffer'
to designate how the incoming data should be collected. Default:'buffer'
.bodyLimit
(number): The maximum payload size, in bytes, that the custom parser will accept. Defaults to the global body limit passed to theFastify factory function
.
Catch-All
Using this, all requests that do not have a corresponding content type parser will be handled by the specified function.
This is also useful for piping the request stream. You can define a content parser like:
fastify.addContentTypeParser('*', function (request, payload, done) {
done()
})
and then access the core HTTP request directly for piping it where you want:
app.post('/hello', (request, reply) => {
reply.send(request.raw)
})
Here is a complete example that logs incoming json line objects:
For piping file uploads you may want to check out .
// Without this call, the request body with the content type application/json would be processed by the built in json parser
fastify.removeAllContentTypeParsers()
fastify.addContentTypeParser('*', function (request, payload, done) {
var data = ''
payload.on('data', chunk => { data += chunk })
payload.on('end', () => {
done(null, data)
})