【Serverless Framework】ローカル環境でAPI Gateway, Lambdaを再現する

# はじめに
APIの開発においてAWSの「API Gateway」と「Lambda」をよく使用されていると思います。
開発する上で、毎回デプロイしてからレスポンスを確認するのは手間がかかり効率的でないということで「Serverless Framework」およびそのプラグインである「serverless offline」を使用してローカルで開発できる環境を作ります。

## Serverless Framework とは
* サーバーレスなアプリケーションを容易に作成、管理、デプロイできるオープンソースなフレームワーク(Node.js製)。
* AWSだけでなく、AzureやGCPなど様々なクラウドサービスに対応している。
* `serverless.yml`に各種設定を定義する。

## serverless offline とは
* Serverless Frameworkで使えるプラグイン
* ローカル環境でAPI Gateway + Lambda の処理を再現してくれる

# 実施内容
本番環境で**API GatewayへのリクエストをトリガーにしてLambdaで定義した関数を実行する** ことを想定し、開発環境をローカルで構築する。

![スクリーンショット 2021-07-31 15.50.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646903/2bc557a9-63d4-52aa-37c8-728617734358.png)

# 構築手順
### 1. Serverless Framework, serverless-offlineのインストール
* serverless frameworkをインストールする。

```bash
# インストール
$ npm install serverless

# 正しくインストールされているか確認
$ serverless --version
=> Framework Core: 2.52.1
   Plugin: 5.4.3
   SDK: 4.2.6
   Components: 3.14.2

```

* serverless-offline プラグインをインストールする。

```bash
$ npm install --save-dev serverless-offline
```

### 2. プロジェクトの作成  
`sls create -t <テンプレートの名前> -n <プロジェクト名>`でプロジェクトを作成します。
serverless frameworkが提供するテンプレートは[こちら](https://www.serverless.com/framework/docs/providers/aws/cli-reference/create#available-templates)を参照してください。
今回はaws-python3を使用したいと思います。
任意のディレクトリに移動したあと、以下を実行します。

```bash
$ sls create -t aws-python3 -n serverlss-sample
```
するとディレクトリ内に`handler.py`と`serverless.yml`が作成されます。

```bash
$ ls
=> handler.py	serverless.yml
```

### 3. handler.pyを確認する
`handler.py`にはLambdaで実行する関数を定義します。
デフォルトでは以下のようにシンプルなhello関数が定義されてます。

```python:handler.py
import json


def hello(event, context):
    body = {
        "message": "Go Serverless v1.0! Your function executed successfully!",
        "input": event
    }

    response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }

    return response
```

### 4. serverless.ymlを編集する
1. 使用するプラグインを記述します。
2. functionsのhelloにeventsを追加します。

```yml:serverless.yml
service: serverless-sample # プロジェクト名
frameworkVersion: '2'
provider:
  name: aws
  runtime: python3.8
  lambdaHashingVersion: 20201221
functions:
  hello:
    handler: handler.hello # handler.pyの関数helloを実行する
    
    # 追加
    events:
      - http:
          path: /test
          method: get

# 追加
plugins:
  - serverless-offline
```

### 5. 起動
以下のコマンドでプロジェクトを起動します。
するとエンドポイントが表示されます。

```bash
$ sls offline start
=>

   ┌─────────────────────────────────────────────────────────────────────────┐
   │                                                                         │
   │   GET | http://localhost:3000/dev/test                                  │
   │   POST | http://localhost:3000/2015-03-31/functions/hello/invocations   │
   │                                                                         │
   └─────────────────────────────────────────────────────────────────────────┘
```

# レスポンスを確認する
エンドポイントにアクセスすると`handler.py`に定義したbodyの内容が正しく表示されます。

```bash
$ curl http://localhost:3000/dev/test
=> {"message": "Go Serverless v1.0! Your function executed successfully!", ............
```

serverless frameworkを用いて、API Gateway, Lambdaの構成をローカル環境で再現することができました。


## 参考
https://serverless.co.jp/blog/25/