- その1 NestJSやLambdaでのnode.jsの話し
- その2 NestJSのサンプルを動かす、Hello World.
- その3 コントローラーを追加する
- その4 DTOを使う
- その5 CRUD generatorを使い modules,controller, service, dto を生成する
- その6 インターセプタ
- その7 ORMでRDBデータベースを扱う
- その8 NestJSをAPI Gateway+AWS Lambdaとしてデプロイ
本題、ここまでその1~7では AWS へのデプロイを一切していない(ふれていない)ので、AWS APIGateway + AWS Lambdaとして NestJSをデプロイします
制約や前提
AWS関連のリソース
- その7まででAWS上でAmazon RDSを使うと、VPC、セキュリティグループ、RDS、VPC内Lambda 等が出てきて ややこしくなるのでRDS無しです。
- NestJSがAPI Gateway + AWS Lambdaとして動くかどうかという観点です
データベースは使わずNestJSのデプロイを試すためPrisma関連はコメントにする
- NestJSでの初期化処理でPrismaServiceがDB接続をしにいくためコメントにする
- 遅延初期化の方法は調べていませんが不明のためコメントで回避します
- 遅延初期化:必要になったときに始めてPrismaServiceでDB接続する
-
implements OnModuleInit
やasync onModuleInit()
で何らか遅延初期化できると嬉しいのだけど・・・
webpack等は使わない、Lambda Layerも使わない
- ひとまず、手軽にできるdistやnode_modulesを使う
- tsconfig.json と serverless.ymlでデプロイするアップロード用のコードzipを調整する
1. serverless.ymlを変更
- distディレクトリをLambda用のソースのzipファイルとして利用、node_modulesをzipに含める
- tsファイルは不要だけどzip内で一緒にしておく
serverless.yml
service: serverless-nest-example
frameworkVersion: "3"
plugins:
- serverless-plugin-typescript
- serverless-plugin-optimize
- serverless-offline
provider:
name: aws
runtime: nodejs18.x
region: us-east-1
package:
individually: true
include:
- dist/**
# exclude:
# - "*"
# - "**/node_modules/aws-sdk/**" # included on Lambda.
# - "!package.json"
functions:
main:
handler: src/main.handler
events:
- http:
method: ANY
path: /
- http:
method: ANY
path: /{proxy+}
2. AWSへAPI GatewayとLabmda関数をデプロイする
- AWSへデプロイ
cd aws-node-typescript-nest
sls deploy
-
sls deploy
実行結果例
$ sls deploy
Running "serverless" from node_modules
Warning: Invalid configuration encountered
at 'functions.main.events.0': unsupported function event
Learn more about configuration validation here: http://slss.io/configuration-validation
Deploying serverless-nest-example to stage dev (us-east-1)
Compiling with Typescript...
Using local tsconfig.json - tsconfig.json
test/app.e2e-spec.ts (19,12): This expression is not callable.
Type 'typeof supertest' has no call signatures.
Typescript compiled.
✔ Service deployed to stack serverless-nest-example-dev (136s)
endpoint: ANY - https://xxx.execute-api.us-east-1.amazonaws.com/dev/{proxy+}
functions:
main: serverless-nest-example-dev-main (69 MB)
2 deprecations found: run 'serverless doctor' for more details
Monitor all your API routes with Serverless Console: run "serverless --console"
API Gatewayのマネジメントコンソール
AWS Lambdaのマネジメントコンソール
-
Lambda は メモリ使用量 1024MB、slsのV3あたりからのデフォルトhttps://www.serverless.com/framework/docs/providers/aws/guide/serverless.yml/#general-function-settings
# Default memory size for functions (default: 1024MB)
)
3. APIを実行
- API GatewayでのLambdaは1つのみ、Lambda function 1つで 複数のエンドポイントを処理する
APIとしての /hello
を curlから実行してみる
$ curl curl https://xxx.execute-api.us-east-1.amazonaws.com/dev/hello
Hello World! my
- CloudWathc LogsでのLambda functionのログ
- 緑が初回(NestJSの初期化で時間かかっている、コールドスタートかな?)
- 青が2回目(速くなった、Lambdaはウォームスタートになっているかな?)
APIとしての /cats/{id}
を curlから実行してみる
curl https://xxx.execute-api.us-east-1.amazonaws.com/dev/cats/123
This action returns a #123 cat
- CloudWathc LogsでのLambda functionのログ
- インターセプターのログが表示されている
- パラメーターとして受けた {id} の文字列が表示されている
4. AWSから API Gateway 、AWS Lambdaを消す
- まっさらに消えるので注意
sls remove
感想
- 1つのLambda function として 複数のAPI・エンドポイントに対応できるのはWebフレームワークのメリット
- APIごとに同じLambda functionなのでコールドスタートも減る
- NestJSのinterceptor、module、Serviceが増えると初期化時間はだんだん長くなりそうに思われる
- 同じLambdaになるので、CloudWatch Logsでのモニタリング・監視等する場合はキーワード等の調整をしていく、ログ出力の改善が必要と思われる
- アップロードするファイルはnode_modules等肥大化するので小さくしていきたい
- NestJSをECS Fargateとして動かすこともやってみたい、ただVPC等が出てくるため、ひと手間かかる、Serverless FrameworkでVPCやサブネット、セキュリティグループ等は定義せず、Terraform等を使いところである