Closed toptal-dave closed 10 months ago
Do you think a better approach would be to use the getHttpAdapter
or getHttpServer
or similar from the returned promise to get the Fastify server?
I was able to fix the code myself using the nestApp.getHttpAdapter().getHttpServer()
to get the instance:
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);
};
I know it's a separate issue but it would be pretty cool to get the serverless documentation updated with a proper example of how to run a Fastify-based Nest.js application in a Lambda. I'm trying this specific solution to reach a balance of speed (which lowers cost in Lambdas) & avoiding running an instance anywhere (as a container or an EC2) to demonstrate and MVP for a project with Nest.js. It's pretty cool to think that you could start a project this way and when traffic increases, with a few small tweaks, you could probably migrate to EKS or Kubernetes.
Actually I don't think that fixes it entirely because when I try to run the code as a containerized Lambda created by SST, I get the following error:
2023-12-31T23:36:48.020Z 5f37cec7-815e-4f51-a59d-7a20e93c69cf ERROR Invoke Error {
"errorType": "TypeError",
"errorMessage": "app.decorateRequest is not a function",
"stack": [
"TypeError: app.decorateRequest is not a function",
" at module.exports (/var/task/node_modules/@fastify/aws-lambda/index.js:23:9)",
" at Runtime.handler (/var/task/dist/main.js:28:50)",
" at process.processTicksAndRejections (node:internal/process/task_queues:95:5)"
]
}
There's a demo repo here. Perhaps using getHttpAdapter().getHttpServer()
isn't the way to get an instance after all...
Your local fastify
dependency version must match the one installed by the @nestjs/platform-fastify
package
@kamilmysliwiec thanks for the response! I'm going through the fundamentals course now so it feels like I'm replying to a celebrity!
Anyway, I took your advice and locked the version to 4.25.1; however, I'm still getting the decorate response error:
The error is as follows:
2024-01-05T11:53:49.911Z 3c1d2db4-a768-4e91-ba05-44c73b9982e2 ERROR Invoke Error {
"errorType": "TypeError",
"errorMessage": "app.decorateRequest is not a function",
"stack": [
"TypeError: app.decorateRequest is not a function",
" at module.exports (/var/task/node_modules/@fastify/aws-lambda/index.js:23:9)",
" at Runtime.handler (/var/task/dist/main.js:28:50)",
" at process.processTicksAndRejections (node:internal/process/task_queues:95:5)"
]
}
I think my next step is actually going to be to abandon the serverless Fastify adapter and see if I can get it working without. I was able to recently deploy to AWS via an ECS+EC2+ASG+ALB setup but for demo-ing and early growth, Lambda would be extremely awesome.
Actually, @kamilmysliwiec , when I restored the code to a prior version that declared the instance separately instead of trying to reference it (here), I was able to get it working. Thanks for the help!
Is there an existing issue for this?
Current behavior
I am following some example code (that needed adapting) to deploy a Nest.js application using Fastify on AWS Lambda. The code is found in this issue and this PR.
When I adapt the code to be error free, I get a type error at the point where I create the
FastifyAdapter
using aFastifyInstance
:Minimum reproduction code
https://github.com/toptal-dave/fastify-adapter-type-error
Steps to reproduce
All I did was replace the original code with the following code in the
main.ts
:Expected behavior
It should be possible to pass a
FastifyInstance
intoFastifyAdapter
without causing a type error because it looks likeFastifyAdapter
takes either options or an instance by the typing:Package
Other package
@fastify/aws-lambda
NestJS version
10.3.0
Packages versions
Also, the output of
npx nest info
:Node.js version
18.19.0
In which operating systems have you tested?
Other
No response