NestJSをAPI Gateway +  AWS Lambdaで構成する（その１）

# はじめに
- いくつかの記事に分けて投稿していく予定です
- NestJS + API Gateway で動かすことを目標にしていきます
- NestJSの使い方等も調べていきます
- [本題](#本題)

## 別ページ
- その１NestJSやLambdaでのnode.jsの話し
- [その２ NestJSのサンプルを動かす、Hello World](https://qiita.com/ssugimoto/items/557e7a7cce5111bf5de7)
- [その３ コントローラーを追加する](https://qiita.com/ssugimoto/items/fcfbc9a176bcf41d7b45)
- [その４ DTOを使う](https://qiita.com/ssugimoto/items/613b8ab54bd6f8de043c)
- [その５ CRUD generatorを使い modules,controller, service, dto を生成する](https://qiita.com/ssugimoto/items/64a9c3cd5cb33e06f4c9)
- [その６ インターセプター](https://qiita.com/ssugimoto/items/dce542a78fdfbaf1e434)
- [その７ ORMでRDBデータベースを扱う](https://qiita.com/ssugimoto/items/45e23d1b2879b083267c)
- [その８ NestJSをAPI Gateway＋AWS Lambdaとしてデプロイ](https://qiita.com/ssugimoto/items/74c26a8219a944d4acc4)


## きっかけ
- AWS Lambda Node.js をTypescriptで開発するのはよくある。TypescriptではなくNode.jsそのまま使う場合もある
- AWS Lambdaを１つ１つのハンドラー（１つ１つのLambda function）だけでなく、共通コンポーネント 等が必要になる
- 複数人でバックエンドを作成していくと、手元で 気軽にsls deploy したりして 知らぬ間にhandlerは指定されているけどコードが無いとか、Lambda Layerが変わったとか、CloudFormation 等が壊れるんじゃないか？
    - CICDに載せる前の段階で動作確認したい
    - GitHub等にpushしていない段階でクラウドに反映したい
    - GitHub等のfeatureブランチに対応した誰でも自由に使えるクラウドのENVが欲しい（クラウド側を壊しても作り直しですむようにしたい）
- Fargateは使いたくない（常時利用料金がかかる）、サーバーレスLambdaとして動かすのは必須
- NestJSはTypescriptでかつ、AWS Lambdaでも動かせるようなので、API Gateway で AWS LambdaとNestJSを動かすことを深く掘り下げていきたい

## NestJS
- https://nestjs.com/ , https://docs.nestjs.com/
- Typescriptで作成できるWebフレームワーク
- [express](https://expressjs.com/)の後継のような存在
- Webアプリケーションのバックエンド相当（Pythonでいうところの FastAPI, Flask,Chalice / JavaでのSpring  ）
- MVC相当、DDD等の考え方を適用できる
- トランザクションスクリプトで、Controller → Service → Dao（Repository）を扱いやすい。分けて考えやすい。
- DIコンテナが備わっている
- Webフレームワークの恩恵を受けられる

## Serverless Framework
- サーバーレスで開発する最もメジャーなツール（と思ってる）
- 誇大かもしれないが、このツールを使わないでAppSyncやAPI Gatewayを開発しつつAWSクラウド側を手軽につくるには Amplify くらいしかない。CDKやTerraformもあるが開発者体験には疑問がある。
- NestJS + API Gatewayの構成ができるみたいだ

## 懸念
- 本来のLabmdaはFunctionモデル
- 昨今 AWS Lambda Web Adapter は注目されている
     - https://github.com/awslabs/aws-lambda-web-adapter
     - Express.jsの場合 https://github.com/awslabs/aws-lambda-web-adapter/tree/main/examples/expressjs
- ルーティングは本来のLambdaの役割とは少し違う
- やってること →  それ`Lambda`でなく`Fargate`で良いのでは?  Fargateの方が負荷にも耐えられるだろうし、コールドスタート自体がないので処理スピードはメリットがある
- Lambda functionごとの設定はできない
     - 使用メモリ、IAMロール
- コールドスタート
    - この対応のために Lambdaを定期実行、Provisioned Concurrencyを使うのは、なんだかなー
    - 行き着くのは`Fargate`で良いのでは？

### サンプルを動かす
- すんなり動きません
- 別記事で記載していきます

## 参考
- https://zenn.dev/saitom_tech/articles/nestjs_on_lambda
- 参考の記事はある、でも 少し古かったりするので、公式の方を見ながら対応していきたい

## 主観
- 個人的には軽量な構成の方が好きです（昨今、大規模・大人数で開発することはないですし）
- ずいぶん昔（かれこれ10年以上前）はWebフレームワーク、フルスタックフレームワークは良いと思いました
- サーバーレスキャッシュで有名な momento の https://github.com/momentohq/serverless-tutorial はLambdaとDynamoDBの非常にわかりやすい
     - DynamoDB接続は src/clients/dynamodb.js
     - momento への接続は src/clients/momento.js
     - サービスclass は、src/accounts/service.js
     - DynamoDBのエンティティclassは、src/accounts/entities/エンティティ.js
     - ハンドラーのラップ、src/handlers/utils.js
     - この辺のソースから考えるトランザクションスクリプトやDDDを考えてみたいと思う

<a id="本題"></a>
# 本題
## Serverless FrameworkでのNestJSのサンプル
- sls V3 前提
- https://github.com/serverless/examples/tree/v3/aws-node-typescript-nest
- ForkしたGitHubリポジトリ https://github.com/ssugimoto/sls-examples