Content-Types & Parsers

JSON by Default — Add Others With addContentTypeParser

Content-Types & Parsers

Fastify parses application/json automatically. For form posts, XML, or raw bytes, register a parser with addContentTypeParser.

4 min read Level 2/5 #fastify#parsers#content-type
What you'll learn
  • Rely on built-in JSON parsing
  • Register additional parsers for XML, CSV, or octet-stream
  • Use @fastify/formbody for application/x-www-form-urlencoded

Fastify ships with a JSON body parser that runs whenever Content-Type matches application/json. Anything else needs a custom parser — or the request body will be undefined in your handler.

Forms

npm i @fastify/formbody
await app.register(import('@fastify/formbody'));

app.post('/login', async (req) => {
  // req.body is { username, password } from a HTML form post
  return signIn(req.body);
});

XML

import { XMLParser } from 'fast-xml-parser';

const parser = new XMLParser();

app.addContentTypeParser(
  'application/xml',
  { parseAs: 'string' },
  async (req, body) => parser.parse(body as string),
);

Return the parsed value (or throw) — Fastify will set req.body to whatever you return.

Raw Bytes

app.addContentTypeParser(
  'application/octet-stream',
  { parseAs: 'buffer' },
  async (req, body) => body, // body is already a Buffer
);

parseAs can be 'string' or 'buffer'. For streaming (huge uploads), skip the parser entirely and use request.raw (a Node stream) inside the handler, or reach for @fastify/multipart.

Match by Pattern

The first argument can be a regex, so one parser handles a family of types like text/csv and application/csv. Note that registering a parser for 'application/json' overrides Fastify’s default — only do so if you need to swap implementations.

Swagger / OpenAPI From Schemas →