AWS Amplifyハンズオンを試してみた

# はじめに
AmplifyでSNSが作れるワークショップ、「[Amplify SNS Workshop][link-1]」を試してみたので、所感やハマりどころなどを共有します。


[link-1]:https://amplify-sns.workshop.aws/ja/
https://amplify-sns.workshop.aws/ja/

実装イメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675893/c06db62b-8a35-9810-1c60-a96b100d057d.png)

## 利用するリソース
- [AWS Amplify][link-2]
    - Webおよびモバイルアプリ開発の為のフレームワーク。
        - Amplify CLI
            - バックエンドをコマンドラインからセットアップできるツール。

- [Amazon Congnito][link-3]
    - Webおよびモバイルアプリの認証、許可、ユーザ管理を行えるサービス。

- [AWS AppSync][link-4]
    - 複数のデバイス、ユーザが使用するWebおよびモバイルアプリのデータをリアルタイムで管理及び同期できるサービス。

- [Amazon DynamoDB][link-5]
    - NoSQLのDBサービス。耐久性があり、低レイテンシ―。

- [Amazon Elasticsearch Service][link-6]
    - 完全マネージド型の全文検索エンジン。

[link-2]:https://aws.amazon.com/jp/amplify/
[link-3]:https://aws.amazon.com/jp/cognito/
[link-4]:https://aws.amazon.com/jp/appsync/
[link-5]:https://aws.amazon.com/jp/dynamodb/
[link-6]:https://aws.amazon.com/jp/elasticsearch-service/
## 作成できる機能
- 新規会員登録、ログイン、ログアウト機能 (Amazon Cognito)
    
- メッセージのList,Post機能 (AWS AppSync,GraphQL,DynamoDB)

- ユーザのフォロー機能 (GraphQL,DynamoDB)
 - Homeのタイムラインに自分とフォローしたユーザのコメントが表示される

- メッセージ検索機能(GraphQL,ElasticSearch,DynamoDB)

![final_architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675893/1120b62a-a56c-5cd8-008b-f39215195221.png)

- https://amplify-sns.workshop.aws/ja/10_getting_started/00_what_you_build.html

## はまったところ
- GraphQLのエラー
    - [全文検索機能実装][link-search]を行っている際にエラーが出ました。
    - 掲載されているファイルをダウンロードしてコピペするとエラーになります。
        - `@searchable` ディレクティブを適切な箇所に挿入することで解消できます。

[link-search]:https://amplify-sns.workshop.aws/ja/60_full_text_search/00_searchable_back_end.html

当該コード

```
type Post
  @model (
    mutations: {create: "createPost", delete: "deletePost", update: null}
    timestamps: null
    subscriptions: { level: public}
  )
  @auth(rules: [
    {allow: owner, ownerField:"owner", provider: userPools, operations:[read, create, delete]}
    {allow: private, provider: userPools, operations:[read]}
    {allow: private, provider: iam ,operations:[create]}
  ])
  @key(name: "SortByTimestamp", fields:["type", "timestamp"], queryField: "listPostsSortedByTimestamp")
  @key(name: "BySpecificOwner", fields:["owner", "timestamp"], queryField: "listPostsBySpecificOwner")
{
  type: String! # always set to 'post'. used in the SortByTimestamp GSI
  id: ID
  content: String!
  owner: String
  timestamp: Int!
}

```

修正後

```diff
type Post
  @model (
    mutations: {create: "createPost", delete: "deletePost", update: null}
    timestamps: null
    subscriptions: { level: public}
  )
  @auth(rules: [
    {allow: owner, ownerField:"owner", provider: userPools, operations:[read, create, delete]}
    {allow: private, provider: userPools, operations:[read]}
    {allow: private, provider: iam ,operations:[create]}
  ])
  @key(name: "SortByTimestamp", fields:["type", "timestamp"], queryField: "listPostsSortedByTimestamp")
  @key(name: "BySpecificOwner", fields:["owner", "timestamp"], queryField: "listPostsBySpecificOwner")
+  @searchable
{
  type: String! # always set to 'post'. used in the SortByTimestamp GSI
  id: ID
  content: String!
  owner: String
  timestamp: Int!
}
```



- `amplify publish` でエラーが発生することがあった

    - 特定の箇所ではないのですが、`amplify publish` を実行し、デプロイする際にエラーが発生することがありました。
        - 少し時間を空けて再度publishを行うことで問題なくデプロイできました。

    - おそらく、スタックの変更を行う際にどこかしらに問題が発生したようなのですが、原因を見つけることができませんでした。
    
# 所感
Amplifyでのバックエンドの実装がめちゃめちゃ簡単でちょっと面白かったです。
対話式で質問に答えていくだけで構築が行えるので、サクサク作れて楽しい。

ただ、使えるリソースが絞られているので、作ろうとしているサービスがAmplifyだけで実装できるのかどうかを検討してから取り組む必要があると思います。
また、基本はベストプラクティスに沿って作成を行っているようですが、結局サービスをある程度は知らないとチューニングや作りこみはできないのかなと思ったりしました。