fastify/help

Serverless docs on Google/Firebase cloud functions seems off

0x80 opened this issue · 4 comments

0x80 commented

The docs mention that you can integrate fastify like this:

const fastify = require("fastify")({
  logger: true,
})

const fastifyApp = async (request, reply) => {
  await registerRoutes(fastify)
  await fastify.ready()
  fastify.server.emit("request", request, reply)
}

exports.app = onRequest(fastifyApp)

But that seems very strange to me, because you are reregistering the routes on every request. And because people use Fastify for its performance, it seems odd that the docs do not mention anything.

I have now solved it like this

let fastifyApp: FastifyInstance | null = null;

async function initializeFastify() {
  if (fastifyApp) return fastifyApp;

  const fastify = Fastify({
    logger: envToLogger[environment] ?? true,
  });

  fastify.addContentTypeParser("application/json", {}, (req, body, done) => {
    // @ts-expect-error payload is not typed
    req.rawBody = payload.rawBody; // Useful if need to compute HMAC
    // @ts-expect-error body is not typed
    done(null, body.body);
  });

  await registerRoutes(fastify);
  await fastify.ready();

  fastifyApp = fastify;
  return fastifyApp;
}
export const webhooks = onRequest(
  async (req, res) => {
    const app = await initializeFastify();
    app.server.emit("request", req, res);
  }
);

Is Fastify so efficient in initializing that this omission is ok in the documentation? It seems very confusing for people like me who are not very familiar with Fastify..

Good spot! Would you like to send a Pull Request to address this issue?

0x80 commented

Thanks for confirming. And sure, but might be after this week...

Are the docs ok with Typescript of should I keep it pure JS?

0x80 commented

@mcollina The code I was porting to cloud functions had a route for Stripe which required a specific setting for the json parser.

  app.addContentTypeParser(
    "application/json",
    { parseAs: "buffer" },
    function (_req, body, done) {
      try {
        const newBody = {
          raw: body,
        };
        done(null, newBody);
      } catch (err) {
        if (err instanceof Error) {
          done(err, undefined);
        }
      }
    }
  );

Can I somehow combine that with the json parser setting from the docs? If I try to do both I get an error that the parser already exists.

Can I make each route use its own parser setting maybe?

Are the docs ok with Typescript of should I keep it pure JS?

JS is better thanks.

Can I make each route use its own parser setting maybe?

Wrap the route and the content-type parser in its own plugin