【初心者向け】Amplify×AppSync×DynamoDBさわってみた

# 概要
例のごとくやってみた系の記事です。タイトル通り各AWSサービスの作成からリクエストまでの一連の流れを説明します。
もちろん公式も[チュートリアル](https://docs.amplify.aws/start/getting-started/installation/q/integration/vue/)を出してくれています(ありがたや)が、そこそこボリューミーかつ英語記事なので、初心者にはこの記事の方が全体感を掴みやすいと思います。
※内容は主観がもりもりなので、どちらかというと雰囲気で捉えてもらえると嬉しいです。

# 背景
近年のWEB進歩はめざましく、特にサーバレス化はWEBサービスを開発するにあたって選択肢の一つとして必ず入ってきます。現に私が現在取引しているクライアントの要件も完全フルマネージドを所望しています。その選択肢としてAWSでは様々なサービスが用意されていますが、AppSyncやDynamoDBもその一つです。
その開発の一環で初めてそれぞれのサービスを使ってみて、大きな魅力と導入に対する若干のハードルを感じたので、これから望む方に多少なりとも導入が楽になるように本記事を執筆しました。

# 登場サービス
- AWS Amplify
- AWS AppSync
- DynamoDB
- Vue.js
※デプロイに利用するCloudFormationやS3がいますが、実装と直接結びつかないため割愛します

# 全体図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737072/3eaf1035-7b13-0ab8-98bf-b4c8a4cc7cd0.png)

# AWS各サービス紹介
### Amplify
> 拡張可能なフルスタックウェブおよびモバイルアプリケーションをより高速に構築します。開始も簡単、スケールも簡単。

[公式より](https://aws.amazon.com/jp/amplify/#:~:text=AWS%20Amplify%20%E3%81%AF%E3%80%81%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB%E3%81%8A%E3%82%88%E3%81%B3,%E3%81%A8%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E3%82%BB%E3%83%83%E3%83%88%E3%81%A7%E3%81%99%E3%80%82)

モバイルやウェブアプリケーションを構築するためのプラットフォームで、Amplify CLIをはじめとするツールを用いて開発からデプロイまでの一連の作業を代行してくれるすごいやつ。
AWSの知識がなくてもそこそこ簡単にリリースまで持っていってくれます。
対応しているAWSサービスもかなりの数あるようです。その中でも本記事では主にAmplify CLIを利用していきます。

### AppSync
> サーバーレスな GraphQL と Pub/Sub API を使用してアプリケーション開発を加速する

[公式より](https://aws.amazon.com/jp/appsync/)
GraphQLとPub/Sub APIをサーバレスとして提供しちゃう賢いやつ。Apache VTL言語(マッピングテンプレート)を用いて実装していきます。
RESTだとリソースベースのAPIになってしまったり、ドキュメント管理が煩雑になって困っているという人はGraphQLに乗り換えてもいいかも。
あとPub/Subのリアルタイム通信ってこんな簡単に実装できちゃうんだって驚いた一品。リアルタム通信機能を実装したいなら選択肢の一つに入れておきたい。

### DynamoDB
> 1 桁ミリ秒単位で規模に応じたパフォーマンスを実現する高速で柔軟な NoSQL データベースサービス

[公式より](https://aws.amazon.com/jp/dynamodb/?trk=25b69acf-1b7a-4158-9bbe-df641171b317&sc_channel=ps&sc_campaign=acquisition&sc_medium=ACQ-P|PS-GO|Brand|Desktop|SU|Database|DynamoDB|JP|JP|Text&ef_id=Cj0KCQjwlemWBhDUARIsAFp1rLU1cxv_KHNIJCy1cEYINcSUK5Z0rKCptNwgqW5dHz1z3IUG785ppcYaAgbFEALw_wcB:G:s&s_kwcid=AL!4422!3!591672863024!e!!g!!%E3%83%80%E3%82%A4%E3%83%8A%E3%83%A2%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9&gclid=Cj0KCQjwlemWBhDUARIsAFp1rLU1cxv_KHNIJCy1cEYINcSUK5Z0rKCptNwgqW5dHz1z3IUG785ppcYaAgbFEALw_wcB)

AppSyncを使う際にデフォルトの選択肢がDynamoDBですが、実はAuroraも使用可能なのでRDBを使いたい人には不向きかも。
RDBと違い選択や結合がかなり苦手（そもそも利用目的が違うので仕方ないですが）なので選択する際は要注意。
ただ、非構造なのでMVP開発に向いていたり、RDSより低レイテンシーだったりとメリットもある。
今回はただ新しい技術をつかってメリ・デメリを知りたい、という背景から採用した。
※正直index設計がきちんとできないと、ElasticSearchやLambdaEdgeとかの力を借りないと実用化までは持ってけなさそう


# 実践
### 前提条件
Node.js：v14.x以降
npm：v6.14.4以降

### フロントエンド準備
本題ではないためかなり省略します。
#### vue3インストール
下記コマンドを実行する。
```
npm install -g @vue/cli
vue create .
npm install
```
#### AmplifyのJSモジュールをインストール
下記コマンドを実行する。
```
npm install aws-amplify 
```
これを使ってjavascriptでAmplifyの各種操作をします。

### Amplify初期設定

#### AmplifyCLIインストール

下記コマンドを実行する。
```
npm install -g @aws-amplify/cli
```
以後はこのAmplifyCLIを使って操作していきます。

#### AmplifyCLIでIAMユーザーを作成

AWSリソースへのアクセスおよびデプロイは、下記で作成するユーザを利用します。

下記コマンドを実行する。
```
amplify configure
```
出力内容に沿ってアカウントを作成する。
```
Follow these steps to set up access to your AWS account:

Sign in to your AWS administrator account:
https://console.aws.amazon.com/
Press Enter to continue

Specify the AWS Region
? region:  us-east-1
Specify the username of the new IAM user:
? user name:  amplify-test
Complete the user creation using the AWS console
https://console.aws.amazon.com/iam/home?region=us-east-1#/users$new?step=final&accessKey&userNames=amplify-test&permissionType=policies&policies=arn:aws:iam::aws:policy%2FAdministratorAccess-Amplify
Press Enter to continue
```
IAMユーザ作成画面に遷移するので「次へ」を選択したのちに、最終画面のアクセスキーIDとシークレットアクセスキーをメモる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737072/6f376d88-bfcd-e2f4-21d6-fd825687a0f8.png)


メモったアクセスキーIDとシークレットアクセスキーを入力する。
必要に応じてProfile Nameを設定する。（その場合は）
```
Enter the access key of the newly created user:
? accessKeyId:  ********************
? secretAccessKey:  ****************************************
This would update/create the AWS Profile in your local machine
? Profile Name:  amplify

Successfully set up the new user.
```

#### AmplifyCLIでプロジェクトを作成
下記コマンドを実行する
```
amplify init
```
今回は下記設定にしました。
※いろいろな設定がありますので、そのプロジェクトに合わせた柔軟な選択が可能です（ios, react ...etc）
```
? Initialize the project with the above configuration? No
? Enter a name for the environment dev
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using vue
? Source Directory Path:  src
? Distribution Directory Path: dist
? Build Command:  npm run-script build
? Start Command: npm run-script serve
Using default provider  awscloudformation
? Select the authentication method you want to use: AWS profile
? Please choose the profile you want to use amplify
```

これで初期設定は完了です。簡単ですね。
このタイミングで大きく２つの役割を持つディレクトリとファイルが生成されます。
- amplify/*：認証、GraphQL API、ストレージなどバックエンド定義を格納するとディレクトリ。機能追加等でバックエンドスタックを定義するIaCテンプレートが追加されていきます。
- src/aws-exports.js：フロントエンド（VueJS等）がバックエンドサービスに関する必要な接続情報を取得するファイルです。main.js等のエントリーポイントで最初に読み込んだりします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737072/c759415c-6d42-cf8d-5eda-0bfe5d2a2115.png)


### GraphQLAPIの作成とAWSリソースをデプロイ



#### AmplifyでGraphQL APIを作成
下記コマンドを実行する。
```
amplify add api
```

今回は下記設定を選びました。
```
? Select from one of the below mentioned services: GraphQL
? Here is the GraphQL API that we will create. Select a setting to edit or continue Continue
? Choose a schema template: Single object with fields (e.g., “Todo” with ID, name, description)
```
すると「api/{project_name}」配下にAppSync関連のリソースファイルが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737072/5293f196-8643-039a-8bc5-5a24a05aa49f.png)

これらを使ってGraphQLAPIを実装していきますが、Amplifyではこの「schema.graphql」を「GraphQL Transform」が抽象化しており、この定義から、CRUDの操作（ミューテーション等）用のスキーマ定義、リゾルバ、DynamoDBの作成まで一気に生成してくれます。（なんて賢いんだ）
```
type Todo @model {
  id: ID!
  name: String!
  description: String
}
```

#### AWSリソースをデプロイ

下記コマンドを実行する。

```
amplify push
```
いろいろ聞かれますが基本「Yes」で大丈夫です。
```
? Are you sure you want to continue? Yes
? Do you want to generate code for your newly created GraphQL API Yes
? Choose the code generation language target javascript
? Enter the file name pattern of graphql queries, mutations and subscriptions src/graphql/**/*.js
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions Yes
? Enter maximum statement depth [increase from default if your schema is deeply nested] 2
```

無事にAWSにAppSyncとDynamoDBのリソースが作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737072/e6215a70-bb59-61a7-40b8-4a5a7f65f474.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737072/81737ae0-d993-7da2-db59-e6d239b36220.png)

また、このタイミングで「src/graphql/*」avascriptのgraphql API操作コードも自動生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737072/95217072-5803-5872-c952-17b427385bea.png)
「＠model」と記述するだけで、ここまでよろしくやってくれます。

あとは、サクッとVueJSで生成された以下のファイルを読み込んでプログラミングするだけです。
- src/aws-exports.js
- src/graphql/*

main.js
```
import { Amplify } from 'aws-amplify';
import awsExports from './aws-exports';
Amplify.configure(awsExports);
```
App.vue
```
<template>
  <ul>
    <li v-for="todo in todoList" :key="todo.id">{{todo.id + ':' + todo.name}}</li>
  </ul>
  <button @click="setTodo()">setTodo</button>
  <button @click="getTodoList()">getTodoList</button>
</template>

<script setup>
import { ref } from 'vue'
import { API } from 'aws-amplify'
import { createTodo } from '@/graphql/mutations'
import { listTodos } from '@/graphql/queries'

const todoList = ref([])

const setTodo = async () => {
  await API.graphql({
    query: createTodo,
    variables: {
      input: {
        name: 'testName',
        description: 'testDescription' 
      }
    }
  })
}

const getTodoList = async () => {
  const result = await API.graphql({
    query: listTodos
  })
  todoList.value = result.data.listTodos.items
}
</script>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737072/8612705d-9840-7f7e-b04c-63ebca917919.png)


簡単ですね！

いかがでしたでしょうか。
今回はそれぞれのAWSリソース作成から利用までの全体の流れを表現しましたが、次回はそれぞれのサービス特徴に踏み込んだ内容をご紹介できればと思います。

[Amplify公式ドキュメント](https://docs.aws.amazon.com/amplify/)
[AppSync公式ドキュメント](https://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/what-is-appsync.html)
[DynamoDB公式ドキュメント](https://docs.aws.amazon.com/ja_jp/dynamodb/?id=docs_gateway)


## 最後に
[AWS開発日記](https://aws.amazon.com/jp/campaigns/manga/vol4-1/)の方がわかりやすいかも？