aws-lambda-fastify icon indicating copy to clipboard operation
aws-lambda-fastify copied to clipboard

updates readme for nestjs

Open Jwagner347 opened this issue 2 years ago • 12 comments

This PR updates the Readme with instructions on running with NestJS and with NestJS/GraphQL. This should also close out https://github.com/fastify/aws-lambda-fastify/issues/115.

Checklist

Jwagner347 avatar Dec 16 '22 20:12 Jwagner347

IMO, this is all knowledge not specific to aws-lambda-fastify, but general to how AWS Lambda works in combination with NestJS... Isn't this making the Readme more noisy?

adrai avatar Dec 16 '22 20:12 adrai

I would say it's about how aws-lambda-fastify works in combination with NestJS, not just generic AWS Lambda. But, I do see your point; however, there is an open issue inquiring about this which led to some more discussion and someone asked me to update the readme in order to persist the knowledge. Maybe that's not the right place for it, though.

Jwagner347 avatar Dec 16 '22 21:12 Jwagner347

I think a better place for this documentation is on the Nest.js website. We do not have the resources to support Nest.js users while they do. i would not block this but I would not LGTM it either.

mcollina avatar Dec 16 '22 22:12 mcollina

I think a better place for this documentation is on the Nest.js website.

We do not have the resources to support Nest.js users while they do.

i would not block this but I would not LGTM it either.

That's exactly what I meant 😉

adrai avatar Dec 16 '22 22:12 adrai

@mcollina I agree. I'll see about getting this added to their documentation.

Jwagner347 avatar Dec 16 '22 22:12 Jwagner347

@Uzlopak ok for you if we close this PR in favor to document it on the Nest.js side somewhere?

adrai avatar Dec 18 '22 10:12 adrai

I am totally ok with it as long it is somewhere documented?!

Is it likely that nest js will accept that additional documentation?

Uzlopak avatar Dec 18 '22 11:12 Uzlopak

Just want to say that I was looking around today and was very happy to find a PR here with documentation about using Next.js with Fastify on Lambda. Is there a PR for Nest.js documentation I can upvote or whatever? I really appreciate being able to find some documentation somewhere on this so I hope it gets out there on the web somewhere somehow...

toptal-dave avatar Dec 30 '23 16:12 toptal-dave

@Jwagner347 I see some issues with the code in the README. Mostly variable names and types not lining up because the code is combined. Here's how it should look:

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import awsLambdaFastify, { PromiseHandler } from '@fastify/aws-lambda';
import fastify, { FastifyInstance, FastifyServerOptions } from 'fastify';
import { Context, APIGatewayProxyEvent } from 'aws-lambda';
import { Logger } from '@nestjs/common';

interface NestApp {
  app: NestFastifyApplication;
  instance: FastifyInstance;
}

let cachedNestApp;

async function bootstrap(): Promise<NestApp> {
  const serverOptions: FastifyServerOptions = {
    logger: (process.env.LOGGER || '0') == '1',
  };
  const instance: FastifyInstance = fastify(serverOptions);
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(instance),
    {
      logger: !process.env.AWS_EXECUTION_ENV ? new Logger() : console,
    },
  );

  const CORS_OPTIONS = {
    origin: '*',
    allowedHeaders: '*',
    exposedHeaders: '*',
    credentials: false,
    methods: ['GET', 'PUT', 'OPTIONS', 'POST', 'DELETE'],
  };

  app.register(require('fastify-cors'), CORS_OPTIONS);

  app.setGlobalPrefix(process.env.API_PREFIX);

  await app.init();

  return {
    app,
    instance,
  };
}

export const handler = async (
  event: APIGatewayProxyEvent,
  context: Context,
): Promise<PromiseHandler> => {
  if (!cachedNestApp) {
    const nestApp: NestApp = await bootstrap();
    cachedNestApp = awsLambdaFastify(nestApp.instance, {
      decorateRequest: true,
    });
  }

  return cachedNestApp(event, context);
};

However, we have a bigger issue and that is a type mismatch when adapting Fastify:

Argument of type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>' is not assignable to parameter of type 'FastifyHttp2Options<any, FastifyBaseLogger> | FastifyHttp2SecureOptions<any, FastifyBaseLogger> | FastifyHttpsOptions<...> | FastifyInstance<...> | FastifyServerOptions<...>'.
  Type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>' is not assignable to type 'FastifyInstance<any, any, any, FastifyBaseLogger, FastifyTypeProviderDefault>'.
    The types of 'withTypeProvider().decorate' are incompatible between these types.
      Type 'DecorationMethod<FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, Provider>, FastifyInstance<...>>' is not assignable to type 'DecorationMethod<FastifyInstance<any, any, any, FastifyBaseLogger, Provider>, FastifyInstance<any, any, any, FastifyBaseLogger, Provider>>'.
        Target signature provides too few arguments. Expected 2 or more, but got 1.

I'll see if I can figure it out and update below.

toptal-dave avatar Dec 30 '23 21:12 toptal-dave

I submitted an bug report issue here.

toptal-dave avatar Dec 30 '23 22:12 toptal-dave

OK I took another crack at fixing it using the Fastify instance from the NestFactory; plus I updated some of the parts to work with the latest Nest version 10.2:

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import awsLambdaFastify, { PromiseHandler } from '@fastify/aws-lambda';
import { Context, APIGatewayProxyEvent } from 'aws-lambda';
import { Logger } from '@nestjs/common';

let cachedNestApp;

async function bootstrap(): Promise<NestFastifyApplication> {
  // Create the app
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    // Use an env var to set the logger to nest or console
    new FastifyAdapter({ logger: (process.env.LOGGER || '0') == '1' }),
    {
      logger: !process.env.AWS_EXECUTION_ENV ? new Logger() : console,
    },
  );

  // Enable cors
  app.enableCors({
    origin: '*',
    allowedHeaders: '*',
    exposedHeaders: '*',
    credentials: false,
    methods: ['GET', 'PUT', 'OPTIONS', 'POST', 'DELETE'],
  });

  // Set the prefix as necessary
  app.setGlobalPrefix(process.env.API_PREFIX);

  await app.init();

  return app;
}

export const handler = async (
  event: APIGatewayProxyEvent,
  context: Context,
): Promise<PromiseHandler> => {
  // If there's no cached app
  if (!cachedNestApp) {
    // Bootstrap
    const nestApp: NestFastifyApplication = await bootstrap();
    // Create an AWS Lambda Fastify cached app from the Nest app
    cachedNestApp = awsLambdaFastify(nestApp.getHttpAdapter().getHttpServer(), {
      decorateRequest: true,
    });
  }

  return cachedNestApp(event, context);
};

toptal-dave avatar Dec 31 '23 22:12 toptal-dave

I got it working!

The code that works is as follows:

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import awsLambdaFastify, { PromiseHandler } from '@fastify/aws-lambda';
import { Context, APIGatewayProxyEvent } from 'aws-lambda';
import { Logger } from '@nestjs/common';
import { fastify, FastifyServerOptions, FastifyInstance } from 'fastify';

interface NestApp {
  app: NestFastifyApplication;
  instance: FastifyInstance;
}

let cachedNestApp;

async function bootstrap(): Promise<NestApp> {
  const serverOptions: FastifyServerOptions = {
    logger: (process.env.LOGGER || '0') == '1',
  };
  const instance: FastifyInstance = fastify(serverOptions);
  // Create the app
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    // Use an env var to set the logger to nest or console
    new FastifyAdapter(instance),
    {
      logger: !process.env.AWS_EXECUTION_ENV ? new Logger() : console,
    },
  );

  // Enable cors
  app.enableCors({
    origin: '*',
    allowedHeaders: '*',
    exposedHeaders: '*',
    credentials: false,
    methods: ['GET', 'PUT', 'OPTIONS', 'POST', 'DELETE'],
  });

  // Set the prefix as necessary
  app.setGlobalPrefix(process.env.API_PREFIX);

  await app.init();

  return {
    app,
    instance,
  };
}

export const handler = async (
  event: APIGatewayProxyEvent,
  context: Context,
): Promise<PromiseHandler> => {
  // If there's no cached app
  if (!cachedNestApp) {
    // Bootstrap
    const nestApp: NestApp = await bootstrap();
    // Create an AWS Lambda Fastify cached app from the Nest app
    cachedNestApp = awsLambdaFastify(nestApp.instance, {
      decorateRequest: true,
    });
  }

  return cachedNestApp(event, context);
};

I had to make sure that the Fastify version was the same between what was installed here and what @nestjs/platform-fastify as per this comment.

toptal-dave avatar Jan 05 '24 14:01 toptal-dave