serverless-http
serverless-http copied to clipboard
serverless-http + Nest.js
Hi guys! Is there a way to use Nest.js with this awesome package?
@dzmitrypanamarenka so here's how I'm doing it, although this has only been partially successful for me:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app/app.module';
import { ExpressAdapter } from '@nestjs/platform-express';
import * as serverless from 'serverless-http';
import * as express from 'express';
const server = express();
export const createNestServer = async expressInstance => {
const app = await NestFactory.create(AppModule, new ExpressAdapter(expressInstance));
app.enableCors();
return app.init();
};
createNestServer(server)
.then(v => console.log('Nest Ready'))
.catch(err => console.error('Nest broken', err));
export const handler = serverless(server);
The two issues I continue to have are:
- Nest only builds and bootstraps after an API call has come in
- Even though it says "watching for changes" and I see it updating when I change a file, Nest doesn't re-bootstrap after the files change.
The result of this is that you have to hit the app twice in order to see the real response and then if you change a file you have to stop it and start it. I would love to know if my above code could be improved to fix these things!
Hey guys,
I do this:
lambda.ts:
import { Context, Handler } from 'aws-lambda'
import { proxyApi } from '../lib/bootstrap-api'
import { ApiModule } from './api.module'
export const handler: Handler = async (event: any, context: Context) =>
proxyApi(ApiModule, event, context)
bootstrap-api.ts:
import './configure-module-aliases'
import { ValidationPipe } from '@nestjs/common'
import { NestFactory } from '@nestjs/core'
import { ExpressAdapter } from '@nestjs/platform-express'
import { Context } from 'aws-lambda'
import express, { Express } from 'express'
import { RavenInterceptor } from 'nest-raven'
import serverless from 'serverless-http'
import {
initializeTransactionalContext,
patchTypeORMRepositoryWithBaseRepository,
} from 'typeorm-transactional-cls-hooked'
import { registerSentry } from './sentry'
export const bootstrapApi = async (module: any) => {
registerSentry()
initializeTransactionalContext()
patchTypeORMRepositoryWithBaseRepository()
const expressApp = express()
const nestApp = await NestFactory.create(
module,
new ExpressAdapter(expressApp),
)
nestApp.enableCors()
nestApp.useGlobalPipes(new ValidationPipe())
nestApp.useGlobalInterceptors(
new RavenInterceptor({
context: 'GraphQL',
}),
)
await nestApp.init()
return { nestApp, expressApp }
}
let cachedHandler: any
export const proxyApi = async (
rootModule: any,
event: any,
context: Context,
) => {
try {
if (!cachedHandler) {
const { expressApp } = await bootstrapApi(rootModule)
cachedHandler = serverless(expressApp)
}
} catch (err) {
console.error('Error bootstrapping API', err)
throw err
}
return cachedHandler(event, context)
}
@TreeMan360 I like how you did it it seems fairly clean. I think you have an error though:
export const handler: Handler = async (event: any, context: Context) =>
proxyApi(ApiModule, event, context)
You don't need an async
here. For me running this with serverless offline gives an error about using a promise and a callback.