AppSyncからAurora ServerlessのmutationをSubscribeしてみた

AppSyncがAurora Serverlessに対応したようだが、チュートリアルのソースにsubscriptionの設定が無かったので試してみた。

■ 本家チュートリアル
https://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/tutorial-rds-resolvers.html

## aws cliの最新化
aws cliがインストールされていることを前提に進めます。
ただしcliが最新化されていないとチュートリアル通り進めないので念の為最新化しましょう。

```
$ pip install awscli --upgrade --user
```

## Aurora Serverless clusterの作成
ここからは、本家チュートリアルとほぼ同じです。2018年11月現在でTokyoリージョンではAurora ServerlessをデータストアとしたAppsyncは利用できないみたいなので、バージニア北部リージョンで試します。

```
aws rds create-db-cluster --db-cluster-identifier http-endpoint-test  --master-username USERNAME \
 --master-user-password COMPLEX_PASSWORD --engine aurora --engine-mode serverless \
 --region us-east-1
```

## AWS Secrets Manager からDBの認証情報を追加
rds clusterへアクセスするための認証情報を作成します。
ローカルに「creds.json」というファイル名を作成し、以下のように記述してください。

```
{
    "username": "USERNAME",
    "password": "COMPLEX_PASSWORD"
}
```
以下コマンドでrds clusterへアクセスするための認証をSecrets Managerを登録します。

```
aws secretsmanager create-secret --name HttpRDSSecret --secret-string ./creds.json --region us-east-1
```

ちなみに自分はこの方法ではうまくいきませんでした・・
マネジメントコンソールから直接登録しても問題無かったので、今回はその方法で回避しました。

■ Secret Managerのマネジメントコンソール
https://console.aws.amazon.com/secretsmanager/home?region=us-east-1#/home

こんな感じで登録しました。
<img width="1816" alt="スクリーンショット 2018-11-25 14.10.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/100291/99fbe1e9-8715-89e0-e179-31fb22ea3b77.png">

## DB&スキーマの作成

DB&スキーマの作成を行なっていきます。ここは本家チュートリアルとほぼ同じです。

```
aws rds-data execute-sql --db-cluster-or-instance-arn "arn:aws:rds:us-east-1:XXXXXXXXXXXX:cluster:http-endpoint-test" \
--schema "mysql"  --aws-secret-store-arn "arn:aws:secretsmanager:us-east-1:XXXXXXXXXXXX:secret:XXXXX-XXXXXX"  \
--region us-east-1 --sql-statements "create DATABASE TESTDB"
```
```
aws rds-data execute-sql --db-cluster-or-instance-arn "arn:aws:rds:us-east-1:XXXXXXXXXXXX:cluster:http-endpoint-test" \
 --schema "mysql"  --aws-secret-store-arn "arn:aws:secretsmanager:us-east-1:XXXXXXXXXXXX:secret:XXXXX-XXXXXX" \
 --region us-east-1 \
 --sql-statements "create table Pets(id varchar(200), type varchar(200), price float)" --database "TESTDB"
```
--aws-secret-store-arnには先ほどマネジメントコンソールから作成したsecretのARNを指定してください。


## AppSyncのスキーマを作成

Appsyncのスキーマを作成していきます。ここから本家とは少し違いSubscriptionの設定を追加しています。また、subscriptionの動作確認で用いないmutationは削除しています。

```
input CreatePetInput {
	type: PetType
	price: Float!
}

type Mutation {
	createPet(input: CreatePetInput!): Pet
}

type Pet {
	id: ID!
	type: PetType
	price: Float
}

enum PetType {
	dog
	cat
	fish
	bird
	gecko
}

type Query {
	listPets: [Pet]
}

type Subscription {
	createPet(id: ID, type: PetType, price: Float): Pet
		@aws_subscribe(mutations: ["createPet"])
}

schema {
	query: Query
	mutation: Mutation
	subscription: Subscription
}
```

## データソースの指定
AppsyncのデータソースにAuroraを指定します。
AppsyncのSchema > Data Sources > Create data sources から先ほど作成したAuroraを指定します。

<img width="1486" alt="スクリーンショット 2018-11-25 14.28.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/100291/d7ff2d67-3594-ead8-8255-a1b5ec21e77c.png">


## Resolverの設定
AppsyncのスキーマとAuroraのスキーマをマッピングさせます。

AppsyncのSchema > ResolverからcreatePetの「Attach」ボタンを選択します。(以下の画像ではすでにAuroraのマッピングが完了しているため「aurora」となっています)

<img width="1570" alt="スクリーンショット 2018-11-25 14.21.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/100291/f324d9eb-6c60-02ad-0326-1d9d3c0132a9.png">

request mapping template を以下のように設定します。ここも本家と同じです。

```
#set($id=$utils.autoId())
{
    "version": "2018-05-29",
    "statements": [
        "insert into Pets VALUES ('$id', '$ctx.args.input.type', $ctx.args.input.price)",
        "select * from Pets WHERE id = '$id'"
    ]
}
```

response mapping template を以下のように設定します。

```
$utils.toJson($utils.rds.toJsonObject($ctx.result)[1][0])
```

以上で設定は終了です。
あとはAmplifyなどでsubscribeしてやればmutationをリアルタイムに検知できるようになります。

https://www.youtube.com/watch?v=e_D4-deatmw