#POST request is hanged when using Fastify adapter in serverless mode

1 messages · Page 1 of 1 (latest)

crude ibex
#

Hi, I have main.ts setup like this to deploy it on google cloud function

import { Request, Response } from '@google-cloud/functions-framework';
import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

let nestApp: NestFastifyApplication;

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  return app.init();
}

export async function api(req: Request, res: Response) {
  nestApp = nestApp ?? (await bootstrap());
  const instance = nestApp.getHttpAdapter().getInstance();
  await instance.ready();
  instance.server.emit('request', req, res);
}

The problem is when I call a POST request, the request is not processed:

curl -X POST http://localhost:8080 -d "name=john"

Though calling a GET request like this works fine

curl http://localhost:8080

I wonder if my setup is not correct. I tried to use @nestjs/platform-express and it works fine also
Minimum reproduction code:
https://github.com/truongtrongtin/nestjs-function/blob/main/src/main.ts

crude ibex
#

Steps to reproduce
Clone the repo

pnpm install
pnpm run start:dev
curl -X POST http://localhost:8080 -d "name=john"

Please help, thanks

coral adder
#

Found the issue 🙂

Seems that google's cloud-functions does some wonkiness to the body in the body-parser that makes fastify not parse it properly for whatever reason and causes the request to hang. Fastify has a mention of this in their docs on serverless. To get around this, you need to pass the option { bodyParser: false } to the NestFactory so that you canadd your own content parser as fastify advises. I did it with this code snippet:

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
    { bodyParser: false },
  );
  app
    .getHttpAdapter()
    .getInstance()
    .addContentTypeParser('application/json', {}, (req, body, done) => {
      console.log('in the content parser');
      done(null, (body as any).body);
    });
  return app.init();
}

After that, it worked as expected