AWS LambdaとAPI Gatewayを使用したPOSTリクエスト対応のサーバーレスアーキテクチャ構築

## はじめに
AWS LambdaとAPI Gatewayを組み合わせることで、インフラ管理が不要でスケーラブルなWebアプリケーションやAPIを簡単に構築できます。

イベント駆動型のアーキテクチャを採用することで、システムのスケーリング、コストの最適化、運用負担の軽減などのメリットを享受できます。

この記事では、Lambda関数をAPI Gatewayで公開し、シンプルなAPIを構築するための具体的な手順を解説します。

## 前提条件
この記事の内容を実施するには、以下の要件が揃っている必要があります。

:::note
**AWSアカウント：**
AWSアカウントを持っていることが前提となります。

**AWS CLIの設定：**
ローカル環境からAWSにアクセスし操作できるよう、AWS CLIをセットアップし、認証情報を構成しておいてください。

**LambdaとAPI Gatewayの基本理解：**
両サービスの基本的な機能や操作方法についての理解が前提となります。公式ドキュメントや入門書を参考に、事前に学んでおくとスムーズです。
:::

## 達成したいこと
**API Gatewayを使ってLambda関数を公開：**
API Gatewayを通じてHTTPリクエストをLambda関数にルーティングする方法を学びます。

**APIの動作確認：**
構築したAPIを実際にテストし、リクエストが正常に処理されているか確認します。

![スクリーンショット 2024-10-05 23.05.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/f4285884-b59e-2b70-bc01-e8e2188a3a81.png)

:::note warn
POSTリクエストの受信と、その内容をLambda関数で処理し、結果を返すプロセスを実装します。
:::

## 補足事項

:::note
**Lambdaが選ばれる理由について**
Lambdaのサーバーレスアーキテクチャにより、トラフィックの増加に応じた自動スケーリングが可能です。これにより、急なアクセス増にも対応できる堅牢なAPIを構築できます。

Lambdaはリクエストに応じて起動されるため、常時稼働するサーバーを持たない構成が可能です。これにより、稼働時間に応じた従量課金が適用され、効率的なコスト管理が実現します。
:::


## 実装手順
## ステップ 1: Lambda関数の作成
最初に、AWS Lambdaで関数を作成し、APIからのリクエストに応答する処理を実装します。

今回はリクエストのボディから「name」を取得し、挨拶メッセージを返すシンプルな関数を作成します。

### 1. AWS Lambdaの作成
AWSコンソールにログインし、Lambdaサービスに移動して「関数の作成」をクリックします。関数名に「HelloWorldFunction」と入力し、ランタイムにはPython 3.x（またはNode.jsなど他のランタイム）を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/01fbfe47-e47f-93af-48cd-917439997495.png)


「関数の作成」ボタンを押して、関数を作成します。

### 2. Lambda関数コードの編集
次に、Lambda関数に処理を追加します。以下はPythonを使用した例です。API Gatewayでエンコードの問題が発生した場合は、Lambda関数側でBase64デコードの処理を追加します。

```python
import json
import base64

def lambda_handler(event, context):
    body = event['body']
    
    # Base64デコードの処理
    try:
        body = base64.b64decode(body).decode('utf-8')
    except Exception:
        pass

    response = {
        'statusCode': 200,
        'body': json.dumps(f"Hello, {body}!")
    }
    return response
```

この関数は、API Gatewayから送信された「name」を受け取り、「Hello, [name]」というメッセージを返します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/08abedf6-a7ec-a900-1a20-ace5d1e90201.png)


### 3. 関数を保存してテスト
コードの編集が終わったら「保存」をクリックし、テストイベントを設定して動作を確認します。

**テストイベントのJSON例:**
```json
{
  "body": "Alice"
}
```

テストを実行し、「Hello, Alice!」と応答が返ってくることを確認します。

## ステップ 2: API Gatewayの設定
次に、API Gatewayを設定し、HTTPリクエストでLambda関数を呼び出せるようにします。

### 1. API Gatewayの作成
AWSコンソールで「API Gateway」に移動し、「APIの作成」をクリックします。次に「HTTP API」を選択し、APIの名前に「HelloWorldAPI」と入力して作成を進めます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/1dd2c3db-f43a-dc7d-10b7-a8ca90eb6b0b.png)


名前を「HelloWorldAPI」と入力し、デフォルト設定のままで「作成」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/39422339-78cb-9af5-71be-fe2adb1599c5.png)

### 2. Lambda統合の設定
作成したAPIの「統合」タブに移動し、「統合の追加」をクリックします。統合タイプとして「Lambda関数」を選択し、先ほど作成した「HelloWorldFunction」を指定して保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/7e9e7970-250b-ec4b-508a-e133e6e14dbb.png)

### 3. APIエンドポイントの設定
APIのルートに「POST /」を設定し、「エンドポイントの作成」を行います。デフォルトの「POST」メソッドを使用して保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/c0efa04b-7151-ae2c-c56b-3fceca783d68.png)

### 4. APIデプロイ
APIをデプロイするには、「デプロイ」ボタンをクリックし、公開URLが生成されます。このURLが、API Gatewayを通じてLambda関数を呼び出すエンドポイントです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/a1800af4-08ba-3d81-b467-455556cdf9c0.png)


## ステップ 3: APIのテスト
公開されたAPIエンドポイントにPOSTリクエストを送って、Lambda関数が正しく応答するか確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/eea5f284-38f7-5bcb-c95e-c520da58fea6.png)


### 1. APIエンドポイントの確認
AWSコンソールでAPI GatewayのエンドポイントURLを確認します。例えば次のようなURLが生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/ac1c6148-52f0-9b67-52a9-b8fa8597bd80.png)


```arduino
$defaultステージ：https://upnujwfjw8.execute-api.ap-northeast-1.amazonaws.com
devステージ：https://upnujwfjw8.execute-api.ap-northeast-1.amazonaws.com/dev
```

### 2. Postmanやcurlを使ってリクエストを送信
APIをテストするために、Postmanやcurlを使用します。以下はcurlのコマンド例です。

```
curl -X POST https://clxi8gxtp1.execute-api.ap-northeast-1.amazonaws.com/devv/HelloWorldFunctionn -d "BOB"
```

:::note warn
curlコマンドでアクセスする際のURLについては、API作成時に設定した**リソースパスが必要**になります。忘れないように注意してください！
:::


### 3. レスポンスの確認
Lambda関数が正常に動作していれば、以下のようなレスポンスが返ってきます。

```json
{
  "Hello, Bob!"
}
```

**実際のプロンプト画面**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/9ffa1c6b-a62f-c43f-b30f-89d19399c527.png)

この手順を通じて、API GatewayとLambdaを組み合わせた簡単なサーバーレスAPIの構築が完了しました！

## まとめ
今回のハンズオンでは、AWS LambdaとAPI Gatewayを使ってシンプルなサーバーレスアーキテクチャを構築しました。このように、サーバーを管理することなくスケーラブルなAPIを実装できることがAWSの強みです。

Lambdaのスケーリング設定やセキュリティグループ、IAMロールなどを適切に設定することで、より実用的なアーキテクチャを作成できます。

## 参考文献
https://qiita.com/moufuyu/items/340048eef98d98f11187

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