DynamoDB Localの導入

# まえがき
[別記事](https://qiita.com/gzock/items/157c8904f415a636a6ed)でaws-sam-initを導入して、サーバーレスアプリケーションの開発を便利に進めることができるようになったが、やはりサーバーレスならDBとしてはDynamoDBが相性が良く、組み合わせて使いたい。
とはいえ、RDBのOracleDBやPostgreSQLと違って、DynamoDBってAWS固有のプロダクトだからローカルで試せないよね・・・どうせ安いし本物のDynamoDB使っても良いけど、なんだかなぁ・・・開発だし・・・
はい。**天下のAWSさんはローカルで動かせるDynamoDBちゃんを公開**してくれています。是非、使わせてもらいましょう。

※追記: 2020年のAWS DevDayにてDynamoDBに関する講演を行う機会がありました。貴重な機会を頂きありがとうございました。
　　　　その際にDynamoDB Localについても言及しています。参考程度に併せてご覧ください。

* [AWS DevDay 2020 E-2 セッション資料: DynamoDBの初心者に伝えたい初めて触るときの勘所](https://www.slideshare.net/ryosasaki376695/dynamodb-238931115)
  * DynamoDB Localへの言及はP44から

# 前提
下記の公式の手順をベースに、Dockerを使ってDynamoDB Localをインストール/実行させるまでの手順を示す。
[DynamoDB ローカル (ダウンロード可能バージョン) のセットアップ](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.html)

また、DynamoDB Localの簡単な管理のためにGUIも導入する。

本手順の実行環境: Ubuntu 18.04 LTS

# DynamoDB Localのdockerイメージを取得

下記のdockerイメージが、Amazonが公開している正式なDynamoDB Localになるので、これを使う。
> [amazon/dynamodb-local](https://hub.docker.com/r/amazon/dynamodb-local)
> DynamoDB local
> DynamoDB local is a downloadable version of DynamoDB that enables developers to develop and test applications > using a version of DynamoDB running in your own development environment.

※もしそもそもdockerをインストールできていないのであれば、[こちら](https://qiita.com/gzock/items/157c8904f415a636a6ed#docker%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)を参考にどうぞ

```
$ docker pull amazon/dynamodb-local
$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
lambci/lambda           python3.6           4a6785b2780d        5 weeks ago         1.07GB
amazon/dynamodb-local   latest              26ea09a4a680        4 months ago        446MB
```

# DynamoDB Localの起動

DBなので裏でずっと起動しておいて欲しいので、`-d`を使ってバックグラウンド実行させる。
また、`-sharedDb`も指定して、どこからつなげようと単一のDBファイルが使われるようにする。
`-inMemory`というオプションもあり、これを使うとデータを保存しない(メモリ内で完結)動作になる。
つまりデータを揮発性なものにしたいのであれば有効なのだが、コンテナそのものが停止すればどうせデータは消失するので指定不要。
データの永続化する方法については[後述](#データの永続化)する。

```
$ docker run -d -p 8000:8000 amazon/dynamodb-local -jar DynamoDBLocal.jar -sharedDb
$ docker ps --no-trunc
CONTAINER ID                                                       IMAGE                   COMMAND                                             CREATED              STATUS              PORTS                    NAMES
1fc4f480133f130913066fac050e718ceab3a52756496f145b5132dc44c50326   amazon/dynamodb-local   "java -jar DynamoDBLocal.jar -inMemory -sharedDb"   About a minute ago   Up About a minute   0.0.0.0:8000->8000/tcp   suspicious_easley
```

DynamoDB Localは結構お利口さんである。
デフォルト状態では、本物のDynamoDBと同じように認証情報やリージョンによって、別々のDBファイルを作成する。
そのため、テーブルを作ったはずが他のアプリからはそのテーブルが見えない、といった事象が起こりうる。(各種情報を揃えれば良いだけだが)
というわけで開発段階では、面倒くささを減らすために-sharedDbを使ったほうが何かと便利だと思う。

> -sharedDb — -sharedDb を指定した場合、DynamoDB では、認証情報やリージョンごとに別のファイルを使用せずに、単一のデータベースファイルを使用します。
> [DynamoDB 使用に関する注意事項:コマンドラインオプション](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.UsageNotes.html#DynamoDBLocal.CommandLineOptions)

また、使い終わってコンテナを止めたいときは、`docker stop [container_id]` を実行

## データの永続化

DynamoDB Localはコンテナなので保存してあるデータは揮発する。普段の開発シーンや検証シーンではそれで構わないことが多い。
ただし何か理由があってデータを永続化したい場合は、`-v`でホスト側をマウントさせつつ、cmdとして`-dbPath [/path/to/db]`をわたすと良い。

```bash
$ docker run -d \
> -p 8000:8000 \
> -v `pwd`/db:/home/dynamodblocal/db \  <-- コレ
> amazon/dynamodb-local:latest \
> -jar DynamoDBLocal.jar \
> -sharedDb \
> -dbPath /home/dynamodblocal/db        <-- コレ
```

この場合、`/home/dynamodblocal/shared-local-instance.db`を外に出してあげる形になる。ただし、/home/dynamodblocalをそのままマウントすると問題がある。DynamoDBLocal.jarが存在しないことになってしまう。そのため"-dbPath"でDB保存先を切り替えてあげると、うまくマウントおよびdbファイルの外だしができる。

# GUIの導入

DynamoDB Localでは、AWSにあるパブリックのDynamoDBとは異なり、GUIが存在しない。
もちろんコマンドやアプリからなら問題なく操作は可能だが、ちょっと面倒くさいよね・・・ということで、OSSでGUIを作ってくれている人がいるので、ありがたく使わせてもらう。
> [dynamodb-admin](https://github.com/aaronshaf/dynamodb-admin)
> *GUI for DynamoDB Local or dynalite.*

## 準備
### nodejsとnpmの導入

dynamodb-adminは、nodejsで動いている。
そのため、nodejsとパッケージ管理ツールのnpmをインストールしておく必要がある。

```
$ apt update
$ apt install nodejs npm
$ nodejs -v
v8.10.0
$ npm -v
3.5.2
```

### dynamodb-adminのインストール

```
$ npm install dynamodb-admin -g
$ export DYNAMO_ENDPOINT=http://localhost:8000
```

## 実行
```
$ dynamodb-admin
```

※プロンプトが戻ってこなくなるので、`&`を付けてバックグラウンド実行させるか、`screen`を使って別セッションで実行させるような形のほうが良いと思う


## 確認
Webブラウザから**http://localhost:8001**にアクセスして、下記のような画面が確認できればOK
あとは、テーブルを作ったり、アイテムを作ったりして、アプリ側からも取得などできれば問題なし。※別記事で書くと思う

![2019-01-16-14-51-31.png](https://qiita-image-store.s3.amazonaws.com/0/80163/4c345a8e-df65-f1e0-f35c-ae4cc9763293.png)