NestJS的にもAWS Lambda with API Gateway的にもアンチパターンな香りがしますが、欲しいものは欲しいので作りました。
なんで作った?
- 手慣れたAWS Lambda & Amazon API GatewayでAPI作りたい
- NestJSにはチャレンジしたかった
- 「無理ってなったらFargate / ECSあたりのコンテナへそのままいけばいいや」という軽い気持ち
インストール方法
npmで入れちゃいましょう。
npm i -S serverless-lambda-nestjs
使い方
NestJSのアプリをラップする形で使います。
Before
大体の記事で紹介されている、Lambdaで動かすための書き方がこんな感じ。
import { APIGatewayProxyHandler } from 'aws-lambda';
import { NestFactory } from '@nestjs/core';
import { Server } from 'http';
import { ExpressAdapter } from '@nestjs/platform-express';
import * as serverless from 'aws-serverless-express';
import * as express from 'express';
import { AppModule } from './app.module';
let cachedServer: Server;
const bootstrapServer = async (): Promise<Server> => {
const expressApp = express();
const adapter = new ExpressAdapter(expressApp);
const app = await NestFactory.create(AppModule, adapter);
app.enableCors();
app.init();
return serverless.createServer(expressApp);
};
export const handler: APIGatewayProxyHandler = async (event, context) => {
if (!cachedServer) {
cachedServer = await bootstrapServer();
}
const result = await serverless.proxy(cachedServer, event, context, 'PROMISE')
.promise;
return result;
};
After
毎回書くことになる長いコードを全部ラップしました。
import { APIGatewayProxyHandler } from 'aws-lambda';
import { ServerlessNestjsApplicationFactory } from 'serverless-lambda-nestjs';
import { ValidationPipe, INestApplication } from '@nestjs/common';
import { AppModule } from './app.module';
export const handler: APIGatewayProxyHandler = async (event, context) => {
const app = new ServerlessNestjsApplicationFactory<AppModule>(
AppModule
);
const result = await app.run(event, context);
return result;
};
INestApplicationのオプション諸々
ServerlessNestjsApplicationFactory
の第二引数でオプションが渡せます。
const app = new ServerlessNestjsApplicationFactory<AppModule>(
AppModule,
{ cors: true }
);
ServerlessNestjsApplicationFactory
の第三引数がコールバックになってるので、そこでいじれます。
const app = new ServerlessNestjsApplicationFactory<AppModule>(
AppModule,
{
cors: true
},
(nestApp) => {
nestApp.useGlobalPipes(
new ValidationPipe({
transform: true,
}),
);
nestApp.useGlobalFilters(new HttpErrorFilter());
return nestApp
},
);
最後に
「Fargateとかぶん回した方がコスパもいいし便利だよね」ということが言えるようになりたいなという気持ちだけはあります。