ServerlessFrameworkでDynamoDBLocalを使う

今更ですが、[Serverless Framework](https://www.serverless.com/)でDynamoDBのローカル開発環境を構築するために、[DynamoDB Local](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.html)を導入したので、その記録です。

## はじめに

[DynamoDB Local](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.html) 自体は、そもそも aws 公式のツールです。

DynamoDB をローカル環境で利用できるように用意されています。

JRE 上で動作するので、Java6以上の実行環境が必要です。[^1]

それを Serverless Framework で使うための [Serverless DynamoDB Local](https://www.serverless.com/plugins/serverless-dynamodb-local/) というプラグインがあります。

プラグインを利用しなくても DynamoDB Localを利用することはできますが、serverless frameworkの設定と一緒にかけたり、seedなどのオプションがあり便利です。


## Serverless Framework で DynamoDB Local の導入手順

プラグインをインストールします。

```shell
# Serverles DynamoDB local pluginの依存モジュールのインストール
npm install -D serverless-dynamodb-local
```

次に、`serverless.yml` に `serverless-dynamodb-local` の plugin の指定を入れます。

`serverless-webpack` や `serverless-offline`のプラグインを一緒に利用するときは、以下の順番で指定します。

```yml
plugins:
  - serverless-webpack
  - serverless-dynamodb-local
  - serverless-offline
```

Serverles DynamoDB local プラグイン のインストール後に、DynamoDB Local 本体をインストールします。
プラグインをインストールすると、以下のコマンドで DynamoDB Local をインストールできます。

```shell
# dynamodb local のインストール
sls dynamodb install
```

インストールが完了すると、 `.dynamodb` ディレクトリが作成され、jarなどが配置されます。

`sls dynamodb start` のコマンドで、DynamoDB Localが起動します。

あとは 以下で設定するポートに対してアクセスして（例: https://localhost:8000）利用するかんじになります。ソースコードからや、awscliからの利用方法は後述します。

### DynamoDB Local の設定

inMemoryで起動したり、初期データ作成をするためのオプションが提供されています。

以下のように `serverless.yml` の `custom` での設定も可能で、[公式](https://www.serverless.com/plugins/serverless-dynamodb-local/)にオプションの説明があるので、細かく設定したい時に見ると良さそうです。

```yaml
custom:
  dynamodb:
    stages:
      - dev
    start:
      port: 8000
      inMemory: true
      migrate: true
      seed: true
      convertEmptyValues: true
```

## serverless-offlineと起動

Serverless Framework のローカル開発環境では、よく `serverless-offline` を利用していると思います。

`serverless-offline`と一緒に利用していれば、 `sls offline` で DynamoDB Local も一緒に起動してくれます。[^2]

`serverless-webpack`も使っている場合は、`sls offline start` で起動する必要があります。

**逆にDynamo Localを個別に起動しておきたい場合** は、 上述の `serverless.yml` のcutom 設定で、 `noStart: true` を設定することで、 `sls offline`で Dynamo Local が一緒に起動しなくなります。

## ソースコードからの利用方法

ローカル開発時だけ、DynamoDB Local に向けて、AWSにプロビジョニングしたときは本物のDynamoDBに接続したいときは、ソースコード上で向き先を変更する必要があります。

これは、[Serverless Frameworkのサンプルコード](https://github.com/serverless/examples/blob/master/aws-node-http-api-dynamodb-local/todos/dynamodb.js)などを参考にするといいでしょう。

オフラインかどうかの判定は、`sls offline` を起動すると、[IS_OFFLINE](https://www.serverless.com/plugins/serverless-offline#the-processenvis_offline-variable)の環境変数が設定されるので、それをみて接続先を切り替えます。

## AWS CLI でのコマンド実行

ローカル開発中に、DynamoDB Localに入っているデータを閲覧、編集、削除などしたい場合があると思いますが、[awscli](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/index.html)でエンドポイントを指定すれば簡単に操作することができます。

```shell
# table一覧
aws dynamodb list-tables --endpoint-url http://localhost:8000

# 指定したテーブルをscan
aws dynamodb scan --table-name <table名>  --endpoint-url http://localhost:8000
```

また、ブラウザ上で操作ができる「JavaScript console」なるもの用意されていて、以下のようにリンクが表示されるんですが、自分の環境ではアクセスしても表示されなかったです。（原因がわかったら追記します。）

```
$ sls dynamodb start
Dynamodb Local Started, Visit: http://localhost:8000/shell
```

## その他

- 上記はDynamoDB Localの設定方法の説明なだけで、DynamoDBのテーブル定義は、別途 [Resouces](https://www.serverless.com/framework/docs/providers/aws/guide/resources/#configuration) で設定する必要があります。CloudFormationの構文で書いていくだけです。
- `serverless.yml` や `serverless.ts` の設定は、`npx sls print` で正しいかチェックできるので利用すると良いでしょう。

[^1]: Docker イメージもあるようで、[docker でも動作](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.DownloadingAndRunning.html)させることができます。
[^2]:  `serverless.yml` での `serverless-offline` プラグインの指定を最後に書く必要があります。