[前編]未経験営業がAmplify × App Sync × Reactでチャット作成してみた

## 目次
1. [概要](#anchor1)
1. [構成の説明](#anchor2)
1. [Amplifyの初期設定](#anchor3)
1. [チャット用のリソースを用意](#anchor4)
1. [おまけ](#anchor5)

<a id ="anchor1"></a>
## 1.概要
awsの便利機能をフル活用して、チャット機能を作成する手順をまとめました。
ただ結構工程が多いので、

前編...バックエンド
後編...フロント

の順で説明していきます。
全体的にざっくりなのはご容赦を。

<a id ="anchor2"></a>
## 2.構成の説明
### Amplify
アプリ開発において、バックエンド側を簡単に構築してくれるプラットフォーム。
「この機能を作るには、AWSのGUIでこれとこれとこれを用意して...」等と、
アーキテクチャに悩む時間を削れます。
### App Sync
GraphQLを扱うことができるサービス。
今回はチャットに使用するAPI部分をこの子に託します
### DynamoDB
AWSのデータベース。
いわゆるNoSQLなデータベースのうち、「キーバリュー形式」に該当します。
レスポンスが早くチャットを作る上ではお勧め。
### 構成のイメージ
![スクリーンショット 2024-01-03 18.02.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664262/64fab1c8-8bbc-70d8-ec7c-68811a4d3c4a.png)
<a id ="anchor3"></a>
## 3.Amplifyの初期設定
ここから手順の説明に入ります。
### Amplify cliのインストール
```
$ npm install -g @aws-amplify/cli
```
### Amplifyとアカウントを紐付け<br/>
#### ⅰ. アカウント紐付け
```
$ amplify configure
```
実行後、awsのサインインコンソールが開きます。
使用したいアカウントのaccess key idとパスワードを入力してログイン。<br/>
#### ⅱ. IAMの紐付け
cliに戻ってリージョンを選択。
↓
ユーザー名に何も入力せずenter
↓
awsのコンソールでIAMを作成

こちらで、Amplify用のIAMが作成完了します。<br/>
#### ⅲ.Amplifyバックエンドの構築

```
$ amplify init
```

こちらも対話形式で、使用するエディタやフレームワークを選択します。
こちらが完了した時点で、CloudFormationのテンプレートが用意されます。

<a id ="anchor4"></a>
## 4.チャット用のリソースを用意
### App syncとDynamoDBをリソースに追加
```
$ amplify add api
```
これまた対話形式。apiの方式はgraphQLを選択してください。このコマンドでソース内に、

「schema.graphql」

ファイルが生成されます。
### 設定したバックエンド環境をデプロイ
```
$ amplify push
```
このコマンドで下記のリソースが生成されます。
・App sync
・DynamoDB
### バックエンド環境をカスタマイズ
以降は納得いくまで下記を繰り返します。

スキーマファイルを変更
↓
都度、下記コマンドを入力
```
$ amplify update api
```
↓
バックエンドをデプロイ
```
$ amplify push
```
実際にチャット動かしてるとバックエンドの考慮漏れとかは結構見えてきます。
その都度このコマンドを叩くので仕組みに慣れておくとよし。

<a id ="anchor5"></a>
## 5.おまけ
#### a.amplidy add apiの際の注意

apiの認証方式をapi keyにした場合、maxでも365日でapi keyの期限が切れます。
(app syncの仕様なのでこれ以上は延長不可能)。
api keyはフロントのソースに埋め込むので、1年に1回更新の必要があります。
 モバイルアプリでチャットを使用する場合にはstoreの申請も必要になるため特に注意。

#### b.スキーマの例
```
# new schema

# This "input" configures a global authorization rule to enable public access to
# all models in this schema. Learn more about authorization rules here: https://docs.amplify.aws/cli/graphql/authorization-rules
input AMPLIFY { globalAuthRule: AuthRule = { allow: public } } # FOR TESTING ONLY!

# This "input" configures a global authorization rule to enable public access to
# all models in this schema. Learn more about authorization rules here: https://docs.amplify.aws/cli/graphql/authorization-rules
# input AMPLIFY {
#   globalAuthRule: AuthRule = { allow: public, provider: aws_iam }
# } # FOR TESTING ONLY!
schema {
  subscription: Subscription
}

type Chat @model(subscriptions: null)
#   @auth(rules: [{allow: public, provider: iam}])
{
  PK: String!
  SK: String!
    @index(
      name: "SortByChatRoom"
      sortKeyFields: ["createdAt"]
      queryField: "listChatsSortByCreatedAt"
    )
    createdAt:AWSDateTime
    message: String
    is_read: Boolean
    sender_id: Int
}

type Subscription {
  onCreateChat(SK: String!): Chat
    @aws_subscribe(mutations: ["createChat"])
  onDeleteChat: Chat @aws_subscribe(mutations: ["deleteChat"])
  onUpdateChat(SK: String!):Chat 
    @aws_subscribe(mutations: ["updateChat"])
}
```

#### c.各キーの説明
PK：プライマリキー。
データの識別のために使用。
少し複雑な運用になるので次の記事で説明します。

SK：ソートキー。
今回はここにチャットルームのidを持たせます。
今回はこのチャットルームで絞り込んだチャットメッセージをGETできるようにしています。

createdAt：メッセージの作成日時
message: メッセージ本文
is_read: 未読 or 既読 
sender_id: 送信者id
## 以降の流れ
フロントの実装については後編で説明致します〜。