| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
|
IMO, this is all knowledge not specific to aws-lambda-fastify, but general to how AWS Lambda works in combination with NestJS... |
Sorry, something went wrong.
|
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. |
Sorry, something went wrong.
|
I think a better place for this documentation is on the Nest.js website. |
Sorry, something went wrong.
That's exactly what I meant 😉 |
Sorry, something went wrong.
|
@mcollina I agree. I'll see about getting this added to their documentation. |
Sorry, something went wrong.
|
@Uzlopak ok for you if we close this PR in favor to document it on the Nest.js side somewhere? |
Sorry, something went wrong.
|
I am totally ok with it as long it is somewhere documented?! Is it likely that nest js will accept that additional documentation? |
Sorry, something went wrong.
|
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... |
Sorry, something went wrong.
|
@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. |
Sorry, something went wrong.
|
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);
};
|
Sorry, something went wrong.
|
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. |
Sorry, something went wrong.
There was a problem hiding this comment.
This PR adds documentation for using @fastify/aws-lambda with NestJS, addressing issue #115 which requested examples of integrating the library with NestJS. The documentation includes two sections: basic NestJS setup and NestJS with GraphQL integration.
Changes:
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
| ], | ||
| controllers: [AppController], | ||
| providers: [AppService], | ||
| }) |
There was a problem hiding this comment.
The code example is incomplete and missing the class decorator and export. The example should start with export class AppModule {} to be a complete and valid TypeScript class definition.
| }) | |
| }) | |
| export class AppModule {} |
Sorry, something went wrong.
| You will also need to modify your `app.module.ts` file: | ||
|
|
||
| ### app.module.ts | ||
| ```typescript |
There was a problem hiding this comment.
The app.module.ts example is missing necessary import statements. At minimum, it should include imports for Module, GraphQLModule, MercuriusDriverConfig, GqlModuleOptions, MercuriusDriver, join, and any other referenced symbols like createXYZLoader, XYZService, XYZModule, AppController, and AppService. Without these imports, the code example cannot be used as-is.
| ```typescript | |
| ```typescript | |
| import { Module } from '@nestjs/common'; | |
| import { GraphQLModule, GqlModuleOptions } from '@nestjs/graphql'; | |
| import { MercuriusDriver, MercuriusDriverConfig } from '@nestjs/mercurius'; | |
| import { join } from 'path'; | |
| import { createXYZLoader } from './xyz.loader'; | |
| import { XYZService } from './xyz.service'; | |
| import { XYZModule } from './xyz.module'; | |
| import { AppController } from './app.controller'; | |
| import { AppService } from './app.service'; |
Sorry, something went wrong.
| let cachedNestApp; | ||
|
|
||
| async function bootstrapServer(): Promise { |
There was a problem hiding this comment.
The variable cachedNestApp is missing a type annotation. It should be typed to match what awsLambdaFastify returns. Consider adding a type annotation such as let cachedNestApp: PromiseHandler | undefined; or let cachedNestApp: any; for clarity.
| let cachedNestApp; | |
| async function bootstrapServer(): Promise { | |
| let cachedNestApp: PromiseHandler | undefined; | |
| async function bootstrapServer(): Promise<NestApp> { |
Sorry, something went wrong.
| context: Context, | ||
| ): Promise<PromiseHandler> => { | ||
| if (!cachedNestApp) { | ||
| const nestApp = await bootstrap(); |
There was a problem hiding this comment.
The function being called is bootstrap() but the function defined above is named bootstrapServer(). This is a critical bug that would prevent the code from working. The call should be changed to bootstrapServer().
| const nestApp = await bootstrap(); | |
| const nestApp = await bootstrapServer(); |
Sorry, something went wrong.
| methods: ['GET', 'PUT', 'OPTIONS', 'POST', 'DELETE'], | ||
| }; | ||
|
|
||
| app.register(require('fastify-cors'), CORS_OPTIONS); |
There was a problem hiding this comment.
The package fastify-cors has been deprecated and replaced with @fastify/cors. The code should use the newer package instead. Update the line to use @fastify/cors and consider importing it at the top of the file rather than using require() inline, which would be more consistent with the TypeScript imports used elsewhere in the example.
Sorry, something went wrong.
| async function bootstrapServer(): Promise { | ||
|
|
||
| const serverOptions: FastifyServerOptions = { | ||
| logger: (process.env.LOGGER || '0') == '1', |
There was a problem hiding this comment.
Using == for comparison is not recommended in TypeScript/JavaScript. Use strict equality === instead: (process.env.LOGGER || '0') === '1'.
| logger: (process.env.LOGGER || '0') == '1', | |
| logger: (process.env.LOGGER || '0') === '1', |
Sorry, something went wrong.
| export const handler = async ( | ||
| event: APIGatewayProxyEvent, | ||
| context: Context, | ||
| ): Promise<PromiseHandler> => { |
There was a problem hiding this comment.
The return type Promise<PromiseHandler> appears to be incorrect. The PromiseHandler type from @fastify/aws-lambda represents the handler function type, not the return value of the handler. The handler should return the actual response from the lambda proxy, which is typically something like Promise<APIGatewayProxyResult>. Consider removing the explicit return type or using the correct return type.
| ): Promise<PromiseHandler> => { | |
| ) => { |
Sorry, something went wrong.
|
|
||
| let cachedNestApp; | ||
|
|
||
| async function bootstrapServer(): Promise { |
There was a problem hiding this comment.
The function bootstrapServer is missing the generic type parameter for its Promise return type. The return type should be Promise<NestApp> instead of just Promise.
| async function bootstrapServer(): Promise { | |
| async function bootstrapServer(): Promise<NestApp> { |
Sorry, something went wrong.
| Notice we are caching the initialized app. In a lambda environment, the handler will be called on each new request. Anything outside the handler may be cached between calls, which lasts as long as AWS has kept the same lambda execution environment up for your function. By storing the initialized app as a variable, we can minimize the cold-start time of our app since it will be constructed once per execution environment spin up. | ||
|
|
||
| ## Usage with NestJS/GraphQL | ||
| In addition to the above, when using NestJS with GraphQL in a lambda environment, you will need to copy your `schema.gql` into your `dist` folder rather than relying on the `autoSchemaFile` option since this tries to write to `/src` directory inside a running lambda function and you are only allowed to write to `/tmp` directory. You can modify your build script in your `package.json` to acheive this: |
There was a problem hiding this comment.
There's a spelling error: "acheive" should be "achieve".
| In addition to the above, when using NestJS with GraphQL in a lambda environment, you will need to copy your `schema.gql` into your `dist` folder rather than relying on the `autoSchemaFile` option since this tries to write to `/src` directory inside a running lambda function and you are only allowed to write to `/tmp` directory. You can modify your build script in your `package.json` to acheive this: | |
| In addition to the above, when using NestJS with GraphQL in a lambda environment, you will need to copy your `schema.gql` into your `dist` folder rather than relying on the `autoSchemaFile` option since this tries to write to `/src` directory inside a running lambda function and you are only allowed to write to `/tmp` directory. You can modify your build script in your `package.json` to achieve this: |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
This PR updates the Readme with instructions on running with NestJS and with NestJS/GraphQL. This should also close out #115.
Checklist
and the Code of conduct