Amplify Gen2 でLambdaを定義したらesbuildされてソースがコンソール上で見えなくなる

## はじめに

Qiitaのアカウントを初めて作成してみて、投稿記事第一号です。
関西の製造業で働いてAWSを勉強中のエンジニアのヤタクマと申します。

今回、Amplify Gen2 を触り始めてAPI GatewayやLambdaといったバックエンド環境をTypeScriptで定義できるというのは便利だなと思い、触ってみたときのメモです。

もともと、Lambdaをpythonで構築していた過去がありSAMを使うとローカルと同じソースがコンソールでも展開されているのでそれと同じ感覚で Amplify Gen2によりCDKでLambdaを定義して試していたら勝手が異なっていたため自分なりに調べていたことのメモです。

## 環境情報

* AWS Amplify Gen2
* Lambda (Nodejs 20)
* 使用言語 TypeScript

## やったこと

1. Amplify Gen2 のチュートリアルの手順したがって、amplify-next-templateのソースをgithub上でとりこみ、Amplify上でデプロイを行いました

https://docs.amplify.aws/nextjs/start/quickstart/nextjs-app-router-client-components/

2.1でやったチュートリアルのソースをベースに、Lambdaを作成してみました

まず、以下のような階層構造で、amplify ディレクトリいかにさらにLambdaを定義するhandler.tsとresource.tsを作成しました。

```
<root dir>
├─amplify
│  │  backend.ts
│  │  package.json
│  │  tsconfig.json
│  ├─function
│  │  └─my-first-function
│  │          handler.ts
│  │          resources.ts
```

3.以下のように、backend.tsと、handler.ts、resources.tsを定義して、チュートリアルで実行したときと同じようにgithubにpushしてから、CI/CDでビルドを行いました


```typescript:backend.ts
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource.js';
import { data } from './data/resource.js';
import { myFirstFunction } from './function/my-first-function/resources';

const backend = defineBackend({
  auth,
  data,
  myFirstFunction,
});

const authenticatedUserIamRole = backend.auth.resources.authenticatedUserIamRole;
backend.myFirstFunction.resources.lambda.grantInvoke(authenticatedUserIamRole);
```

 ```typescript:handler.ts
import { Handler } from 'aws-lambda';

export const handler: Handler = async (event, context) => {
    return{
        statusCode : 200,
        body:JSON.stringify('Hello from my first function!'),
    };
}
```

```typescript:resources.ts
import { defineFunction } from '@aws-amplify/backend';

export const myFirstFunction = defineFunction({
    name:"my-first-function",
    entry:"./handler.ts",
    timeoutSeconds: 30,
    runtime : 20,
});
```

4.Amplify Gen2で定義したLambdaは、「関数」というところから確認ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3868608/7ce4a032-ec16-2620-29d8-e38e1f81ff14.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3868608/16117959-8db6-5a86-dbcb-ef47cc76227b.png)


今回Amplify Gen2上で定義したLambda名は "my-first-function"ですが、
amplify-d2s3xbfwsdflun-ma-myfirstfunctionlambdaF5A-rtBVKUU664Hh　と
思っていたLambda名とは異なる関数名となります。

(Amplify Gen2で構築されるLambda名は、ユニークなUUIDが割り当てられていたりします)

## コンソール上のLambda

コンソール上のLambdaをみると、手元で定義したhandler.tsのソースがそのままLambdaでデプロイされているのではなく index.mjsという形式のトランスパイルされたプログラムが配置されております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3868608/4810c929-27be-fd01-d2f7-6cd00c3d5142.png)


ただしこのLambda関数を実行してみるとAmplify Gen2上で定義したコード通りには返ってくる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3868608/61fbd30a-9f8d-ee05-15f1-f5ebc0406128.png)

## なぜ異なるのか

Lambdaは直接TypeScriptの言語をサポートはしておらず、esbuildによるJavaScriptへトランスパイルしてからデプロイが行われるみたいです


https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-typescript.html

https://aws.amazon.com/jp/blogs/news/amplify-functions-create-serverless-functions-using-typescript-powered-by-aws-lambda/

## もし同じソースをコンソールで見るなら

ローカル環境で esbuildを実行して zipにしてからそれをアップロードするというやり方になりそう・・・
(Amplify Gen2でLambdaの部分だけ)

https://docs.aws.amazon.com/lambda/latest/dg/typescript-package.html#aws-cli-ts