Search code examples
nestfastifynestjs-fastify

How to add custom content type parser for Nest with Fastify


I need to overwrite the content parser for application/json so my application accepts empty body. Right now it throws:

{
    "statusCode": 400,
    "code": "FST_ERR_CTP_EMPTY_JSON_BODY",
    "error": "Bad Request",
    "message": "Body cannot be empty when content-type is set to 'application/json'"
}

I'm trying with:

import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
import { NestFactory } from '@nestjs/core';

const fastifyAdapter = new FastifyAdapter({
   addContentTypeParser: // what should go here
});

const app = await NestFactory.create<NestFastifyApplication>(AppModule, fastifyAdapter);

but I can't figure out what is expected under addContentTypeParser


Solution

  • To allow empty json body, you can add a content body parser like the following. Instead of throwing FST_ERR_CTP_EMPTY_JSON_BODY error, this will set request body to null.

    const fastifyAdapter = new FastifyAdapter();
    
    fastifyAdapter.getInstance().addContentTypeParser(
      'application/json',
      { bodyLimit: 0 },
      (_request, _payload, done) => {
        done(null, null);
      }
    );
    
    

    You can also set the request body to any value you want using the second argument of the done method.

    Setting body to an empty object for example, would be look like this:

    const fastifyAdapter = new FastifyAdapter();
    
    fastifyAdapter.getInstance().addContentTypeParser(
      'application/json',
      { bodyLimit: 0 },
      (_request, _payload, done) => {
        done(null, {});
      }
    );
    
    

    Also, for those who are getting FST_ERR_CTP_INVALID_MEDIA_TYPE error like me, adding a catch-all content type parser for empty body requests fixes the issue.

    const fastifyAdapter = new FastifyAdapter();
    
    fastifyAdapter.getInstance()
      .addContentTypeParser(
        '*',
        { bodyLimit: 0 },
        (_request, _payload, done) => {
          done(null, null);
        }
      );
    

    Tus clients, by default sends a POST request with no content-type and an empty body. Using a catch-all parser fixed my problem.