DynamoDBlocalでDynamoDBをひとまず触れるようにする

![新規キャンバス.png](https://qiita-image-store.s3.amazonaws.com/0/2278/0bdd1a33-b7a7-e156-0c33-05767c6001f2.png)


## 概要

DynamoDBはAWSのマネージドサービスの一つです。
DynamoDBは、開発のために手元のPCで動作させることができます。
本記事では、以下の方法をご紹介します。

- DynamoDBLocalを手元のPCに入れる
- aws-cliでDynamoDBを操作する
- Go言語でDynamoDBを操作する


## DynamoDBLocalを手元のPCに入れる

以下のURLから、DynamoDBLocalをダウンロードします。
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.html

アーカイブを解凍したら、以下のコマンドでDynamoDBローカルを立ち上げます。

```sh
$ java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
```

`http://localhost:8000/shell/`にアクセスするとJavascriptで操作することもできます。

## aws-cliで操作する

aws-cliで操作するときのポイントは、以下のとおりです。

- `--endpoint-url` に `http://localhost:8000`を指定する
- ローカルでも`--profile`または`AWS_PROFILE`の設定が必要となる


### テーブルを作成する

```sh
$ aws dynamodb create-table --table-name Persons \
   --attribute-definitions AttributeName=Id,AttributeType=N \
  --key-schema AttributeName=Id,KeyType=HASH \
  --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 \
  --endpoint-url http://localhost:8000
```

### テーブル一覧を表示する

```sh
$ aws dynamodb list-tables --endpoint-url http://localhost:8000
```


### テーブルにデータを挿入する

```sh
$ aws dynamodb put-item --table-name Persons --item '{"Id":{"N":"1"},"Name":{"S":"Jack"}}' --endpoint-url http://localhost:8000
```

### データを取得する

```sh
$ aws dynamodb get-item --table-name Persons --key '{"Id":{"N":"1"}}' --endpoint-url http://localhost:8000
```

### データをスキャンする

```sh
$ aws dynamodb scan --table-name Persons --endpoint-url http://localhost:8000
```

## Go言語で操作する

### ダミーのCredentialsを用意しておく

ローカルなDynamoDBに接続する際もCredentialを設定する必要があるので、以下のようにダミーを設定しておきます。

```sh
# ~/.aws/credentials
[dummy]
aws_access_key_id = dummy
aws_secret_access_key = dummy
```

### SDKの導入

```sh
go get -u github.com/aws/aws-sdk-go
```

### ひとまず参照するコード

aws-cliで作成したPersonsテーブルからデータを取得するコードです。

```go
// main.go
package main

import (
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/dynamodb"
	"fmt"
	"github.com/aws/aws-sdk-go/aws/credentials"
)

func main() {
	dynamoSession, err := session.NewSession(&aws.Config{
		Region: aws.String("ap-northeast-1"),
		Endpoint: aws.String("http://localhost:8000"),
		Credentials: credentials.NewStaticCredentials("dummy", "dummy", "dummy"),
	})
	if err != nil {
		panic(err)
	}

	db := dynamodb.New(dynamoSession)

	res, err := db.GetItem(&dynamodb.GetItemInput{
		TableName: aws.String("Persons"),
		Key: map[string]*dynamodb.AttributeValue{
			"Id": {
				N: aws.String("1"),
			},
		},
		AttributesToGet: []*string{
			aws.String("Name"),
		},
		ConsistentRead: aws.Bool(true),
		ReturnConsumedCapacity: aws.String("NONE"),
	})

	if err != nil {
		panic(err)
	}

	fmt.Println(*res.Item["Name"])
}
```

### guregu/dynamoを使用する

https://github.com/guregu/dynamo

ORMのようなものです。
jsonモジュールのように、構造体にマッピングしてくれます。

```sh
$ go get github.com/guregu/dynamo
```

```go
// main.go
package main

import (
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/guregu/dynamo"
)

type Person struct {
	ID int `dynamo:"Id"`
	Name string `dynamo:"Name"`
}

func main() {
	dynamoSession, err := session.NewSession(&aws.Config{
		Region: aws.String("ap-northeast-1"),
		Endpoint: aws.String("http://localhost:8000"),
		Credentials: credentials.NewStaticCredentials("dummy", "dummy", "dummy"),
	})
	if err != nil {
		panic(err)
	}

	db := dynamo.New(dynamoSession)
	table := db.Table("Persons")

	var ret Person
	err = table.Get("Id", 1).One(&ret)
	if err != nil {
		panic(err)
	}

	println(ret.Name)
}
```