Chalice on Local

## この記事の目的
この記事の目的は、AWS製のサーバーレスフレームワークChaliceとDynamoDBを組み合わせて利用する手順を個人的なメモとして記すことです。

[前回](https://qiita.com/akiraabe/items/f10aad4b500770ee327c)の内容を補完する意味で**ローカルでの実行**に特化しています。

以下の内容を含みます。
* Chalice, DynamoDBLocalを用いてローカルマシンで利用します
* ローカル環境でのIDEを利用したデバッグ
* docker-composeを利用して、DynamoDBLocalを起動します

## 前提事項
以下のインストールについては済んでいるものとします。
* Python3
* chalice
* docker-compose

:::details ちなみに、私の環境は以下のようになっています。(2022/1/24時点）
- Python 3.8.9 (Pipenv利用)
- chalice 1.26.4
- AWS-CLI 2.4.11
- docer-compose 2.1.1
- VSCode 1.63.2
- macOS Monterey 12.1
:::

## References

[Chalice公式サイト https://aws.github.io/chalice/index.html](https://aws.github.io/chalice/index.html)

## 基本的な構築手順

前回記事やChalice公式サイトを参照ください。

## DynamoDB localをdocker-composeで起動する。

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.DownloadingAndRunning.html

ソースコードとは別のディレクトリ（同列の階層にする）に、docker-compose.ymlを作成します。

```yaml:docker-compose.yml
version: "3.8"
services:
  dynamodb-local:
    command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data"
    image: "amazon/dynamodb-local:latest"
    container_name: dynamodb-local
    ports:
      - "8000:8000"
    volumes:
      - "./docker/dynamodb:/home/dynamodblocal/data"
    working_dir: /home/dynamodblocal
  dynamodb-admin:
    container_name: dynamodb-admin
    image: aaronshaf/dynamodb-admin:latest
    environment:
      - DYNAMO_ENDPOINT=dynamodb-local:8000
    ports:
      - 8001:8001
    depends_on:
      - dynamodb-local

```

DynamoDB Localとdynamodb-adminを起動します。
```shell
% docker-compose up
[+] Running 2/1
 ⠿ Container dynamodb-local  Created                                                                                                                                 0.1s
 ⠿ Container dynamodb-admin  Created                                                                                                                                 0.0s
Attaching to dynamodb-admin, dynamodb-local
dynamodb-local  | Initializing DynamoDB Local with the following configuration:
dynamodb-local  | Port: 8000
dynamodb-local  | InMemory:     false
dynamodb-local  | DbPath:       ./data
dynamodb-local  | SharedDb:     true
dynamodb-local  | shouldDelayTransientStatuses: false
dynamodb-local  | CorsParams:   *
dynamodb-local  | 
dynamodb-admin  |   database endpoint:  dynamodb-local:8000
dynamodb-admin  |   region:             us-east-1
dynamodb-admin  |   accessKey:          key
dynamodb-admin  |
dynamodb-admin  |   dynamodb-admin listening on http://localhost:8001 (alternatively http://0.0.0.0:8001)
```

## dynamodb-adminでテーブルを作成する。
localhost:8001でdynamodb-adminのGUIに入れます。

CreateTableをします。（テーブル名とキーだけ指定すれば良いです）
![dynamodb-admin-screen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130262/62a83493-0c0a-e898-b14b-17b7fcbdf122.png)

## chalice localコマンドでローカル実行！

### config.jsonにローカル用の定義を追加
以下のように、stagesにlocalの定義を追加します。

```diff JSON:.chalice/config.json
{
  "version": "2.0",
  "app_name": "chalice_demo",
  "stages": {
    "dev": {
      "api_gateway_stage": "api",
      "environment_variables": {
        "DB_TABLE_NAME": "Records"
      },
      "autogen_policy": false
-    }
+    },
+    "local": {
+      "environment_variables": {
+        "IS_LOCAL": "true",
+        "DB_ENDPOINT": "http://localhost:8000",
+        "DB_TABLE_NAME": "LocalRecords"
+      }
+    }
  }
}

```

説明：
いずれも環境変数の設定です。
- IS_LOCAL : ローカル実行か否かを示します（今後の記事で予定している認証の切り替えに使います）
- DB_ENDPOINT : DynamoDB Localのエンドポイントを指定します
- DB_TABLE_NAME : テーブル名です（ローカル用にあえて値を変えています）

### ローカルでchaliceを実行します。

注意！
デフォルトだとstageはdev, portは8000となります。
いずれも、他で使用しているため、明示的にコマンド引数で指定します。

```shell
% chalice local --stage local --port 8080
Serving on http://127.0.0.1:8080
```
chalice local で --stage localとするのはかなり間抜けですが...
余談ですが、--stageを指定しないと、awsのDynamoDBにつながります。（awsのクレデンシャルを設定している場合）

### ローカルのAPIエンドポイントを叩いてみる！（出力は見やすく整形しています）
```
% curl localhost:8080/records/166d6c4323d742bc9af87fcc0c3e2241
{
  "sub":"LOCAL_USER",
  "result_time":"00:24:59",
  "race":"3",
  "runner_name":"test-runner3",
  "description":"Memo3",
  "section":"3",
  "id":"166d6c4323d742bc9af87fcc0c3e2241",
  "team":"TeamX"
}
```

### IDEでのデバッグ実行
IDEにはPyCharmを使いました。（VSCodeと迷いましたが、デバッグの設定に関してはPyCharmの方が簡単だったので）

実行済みのchalice localのプロセスにアタッチします。
![debug1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130262/c0945a69-d59a-aa60-baaa-6f7851df5132.png)


プロセスを選択します。
![debug2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130262/99821b71-ca15-dd9e-d155-c7c95a90c981.png)


ブレイクポイントで停止し変数のウォッチなどができます。（通常のデバッグと同様です）
![debug3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130262/b112fc3a-edbf-754b-0571-adb74e63c4ea.png)



## まとめ
今回は、Chalice on Localということで、ローカルでの実行とデバッグを行いました。

正直、awsにデプロイする方が手っ取り早い気もしますが、アプリケーションのロジックのデバッグがローカルで出来ると良い面もあるので、方法を知っておいても損はないかなぁと思いました。

次は、認証でAPIを保護するというのを試してみたいと思います。

ソースコードは、[GitHub](https://github.com/akiraabe/chalice_demo_pj)にあげてあります。