Spring Boot 2.0でAWSのDynamoDBにとにかく早くつなげたい

# 1. 概要

題名のとおり、忙しい人のために
テンプレートを共有します。

[githubリポジトリ](https://github.com/otomori-k/dynamo-sample)

やることは以下の3つです。

- AWSの接続情報を設定
- DynamoDBでテーブルを作成
- ビルドして実行

# 2. 詳細

## AWSの接続情報を設定

AWS CLIをインストールしてください。
[AWS CLIのインストール](https://qiita.com/yuyj109/items/3163a84480da4c8f402c)を参考にしてください。

```
aws configure
```

- アクセスキー
- シークレットアクセスキー
- リージョン
- 形式

を設定します。
設定ファイルは

- ~/.aws（Linux）
- C:\Users\ユーザ名\.aws（Windows）

どちらかに作成されます。

## DynamoDBでテーブルを作成

マネジメントコンソールから、
テーブルを作成してください。

![2018-04-12_173724.png](https://qiita-image-store.s3.amazonaws.com/0/132064/ef5c7be6-3d35-0f2b-28b3-180eabd0dec9.png)

- サンプルではテーブル名は「Table」
- サンプルではプライマリキーは「id」

![2018-04-12_173802.png](https://qiita-image-store.s3.amazonaws.com/0/132064/56a7f490-6739-6428-4b1f-c210216fd707.png)

テーブルが作成されると、項目名を見ることが出来ます。
（中身はまだ空です。）

![2018-04-12_173834.png](https://qiita-image-store.s3.amazonaws.com/0/132064/299763e0-b791-846b-eb32-8535369b2d0f.png)

## ソース

プロジェクトは以下の構成です。

```
dynamo-sample
│  .gitignore
│  build.gradle
│  gradlew
│  gradlew.bat
│  .gradle
│  gradle
│
└─src
    └─main
        ├─java
        │  └─com
        │      └─example
        │          │  Application.java
        │          │  DynamoDBConfig.java
        │          │
        │          ├─model
        │          │      User.java
        │          │
        │          ├─repositories
        │          │      UserRepository.java
        │          │
        │          └─resource
        │                  UserController.java
        │
        └─resources
            └─config
                    application.yml
```

依存モジュールのバージョンは[こちら](https://github.com/derjust/spring-data-dynamodb)を参考にしました。

```build.gradle
buildscript {
	ext {
		springBootVersion = '2.0.0.RELEASE'
	}
	repositories {
		mavenCentral()
	}
	dependencies {
		classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
	}
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
	mavenCentral()
}


dependencies {
	compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
    compile('org.springframework:spring-webmvc:5.0.4.RELEASE')
    compile('com.github.spring-data-dynamodb:spring-data-dynamodb:5.0.2')
    compile group: 'org.springframework.data', name: 'spring-data-releasetrain', version: 'Kay-SR1', ext: 'pom'
    compile group: 'com.google.guava', name: 'guava', version: 'r05'

}
```

application.ymlはリージョンによってエンドポイントの変更が必要です。

```application.yml
amazon:
  dynamodb:
    endpoint: https://dynamodb.ap-northeast-1.amazonaws.com
  credential:
    profile: default
```

DynamoDBと接続するためのマネージャクラスです。

```DynamoDBConfig.java
package com.example;

import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;

@Configuration
@EnableDynamoDBRepositories(basePackages = "com.example.repositories")
public class DynamoDBConfig {
    @Value("${amazon.dynamodb.endpoint}")
	private String amazonDynamoDBEndpoint;

    @Value("${amazon.credential.profile}")
    private String profile;

	@Bean
	public AmazonDynamoDB amazonDynamoDB() {
		AmazonDynamoDB amazonDynamoDB = new AmazonDynamoDBClient(amazonAWSCredentials());
		if (!StringUtils.isEmpty(amazonDynamoDBEndpoint)) {
			amazonDynamoDB.setEndpoint(amazonDynamoDBEndpoint);
		}
		return amazonDynamoDB;
	}

	@Bean
	public AWSCredentials amazonAWSCredentials() {
		return new ProfileCredentialsProvider(profile).getCredentials();
	}
}
```

一般的な起動クラスです。

```Application.java
package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

}
```

エンドポイントです。
今回は簡単にユーザ名を登録するだけの内容にしています。

```UserController.java
package com.example.resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.model.User;
import com.example.repositories.UserRepository;

@RestController
public class UserController {

	@Autowired
	private UserRepository userRepository;

	@GetMapping("/init")
	private void init() throws Exception {
		userRepository.save(new User("taro"));
	}

}
```

モデルです。

```User.java
package com.example.model;

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAutoGeneratedKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;

@DynamoDBTable(tableName = "Table")
public class User {

	private String id;
	private String name;

	public User() {
	}

	public User(String name) {
		this.name = name;
	}

	@DynamoDBHashKey
	@DynamoDBAutoGeneratedKey
	public String getId() {
		return id;
	}

	@DynamoDBAttribute
	public String getName() {
		return name;
	}

	public void setId(String id) {
		this.id = id;
	}

	public void setName(String name) {
		this.name = name;
	}

}
```

DynamoDBのテーブル操作を定義する抽象クラスです。

```UserRepository.java
package com.example.repositories;

import java.util.List;

import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
import org.springframework.data.repository.CrudRepository;

import com.example.model.User;

@EnableScan
public interface UserRepository extends CrudRepository<User, String> {
	List<User> findByName(String name);
}
```

## ビルドして実行

上記リポジトリをビルドして
実行してください。

```
gradlew bootrun
./gradlew bootrun
```

ブラウザで下記にアクセスします。
http://localhost:8080/init

![2018-04-12_175614.png](https://qiita-image-store.s3.amazonaws.com/0/132064/1f0283f1-512e-6149-107b-6b184f48fd04.png)

返戻値がないので何も出ません。

AWSコンソールを確認すると
データが登録されていることがわかります。

![2018-04-12_175643.png](https://qiita-image-store.s3.amazonaws.com/0/132064/a0aa68c4-29b8-5d42-41bd-4687cb25e302.png)

# 3. まとめ

私は依存モジュールのバージョンのところで、かなりの時間を費やしてしまいました。
[テンプレート](https://github.com/otomori-k/dynamo-sample)を使っていただき、みなさん幸せになってもらいたいと思います。
コードのご指摘もいただければ幸いです。