fastify / help

Need help with Fastify? File an Issue here.
https://www.fastify.io/
64 stars 8 forks source link

Serverless docs on Google/Firebase cloud functions seems off #1042

Open 0x80 opened 1 month ago

0x80 commented 1 month ago

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..

mcollina commented 1 month ago

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

0x80 commented 1 month ago

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 1 month ago

@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?

mcollina commented 1 month ago

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