2019.01.07
AWS Amplifyを使ってバックエンドを構築するプロジェクトにて、$ amplify push
すると、ルートディレクトリにamplify
という名前のディレクトリができる。
カテゴリとしてApi
・Auth
・Hosting
を追加した状態のディレクトリは以下のようになっている。
# 2階層までツリー表示
$ tree -L 2 amplify
amplify
├── #current-cloud-backend
│ ├── amplify-meta.json
│ ├── api
│ ├── auth
│ └── hosting
└── backend
├── amplify-meta.json
├── api
├── auth
├── awscloudformation
└── hosting
#current-cloud-backend
とbackend
で同じようなディレクトリ構造をしていて紛らわしい。それぞれ以下のような役割となっている。
フォルダ名 | 役割 |
---|---|
#current-cloud-backend | 最新のバックエンドの状況が反映されるディレクトリ |
backend | ローカルのバックエンドに関する設計を置く場所ディレクトリ |
#current-cloud-backend
は、AWS Amplifyの前身であるAWS Mobile SDKにはフロントエンドのプロジェクトでバックエンドの環境を構築するような機能がなかった頃、バックエンドの情報をフロントエンドに持ってくる機能で使っていたディレクトリの名残とのこと。AWS Amplifyを使う上で、特に変更する必要のないディレクトリ。
AWS AppSyncのマネジメントコンソールでは、以下のような画面でスキーマを記述していく。
スキーマに記述した内容を元に右側の表のエリアに情報が表示されるので、そこからリゾルバーをアタッチすることになる。 リゾルバーの変更は以下のような画面で行うことになる。
AppSyncのスキーマやリゾルバーはこのマネジメントコンソールから設定することもできるが、せっかくAWS Amplifyを使ってフロントエンドのプロジェクトでバックエンドの設定ができるので、フロントエンドのプロジェクトで全て完結させることが理想的。
AWS Amplify経由でAPIを変更しないと、次回$ amplify push
したときにせっかく変更したスキーマやリゾルバーがフロントエンドのプロジェクトの設定内容で上書きされてしまう。
AWS Amplify経由でAppSyncをAPIエンドポイントとして作っていく際には、そのスキーマ設計をamplify/backend/api/<プロジェクト名>/schema.graphql
に記述していく。
$ amplify add api
コマンドを実行すれば対話形式で設定することができるので、以下のようなスキーマが書かれているかもしれない。
type Task
@model
{
id: ID!
title: String!
description: String
}
このschema.graphql
にスキーマを書いた状態で$ amplify push
することで、自動的にリゾルバーが作成されて、バックエンドのAppSyncに設定が適用される。
リゾルバーはフロントエンドのプロジェクトのamplify/backend/api/<プロジェクト名>/build/resolvers
というディレクトリにMutation.createTask.request
のように作成されるが、こちらも変更してしまうと次回の$ amplify push
の実行時に上書きされてしまう。
AWS Amplifyを使う上では、リゾルバーを直接変更することは避けてschema.graphql
を変更してAppSyncを設定する必要がある。
もしschema.graphql
の変更では生成できないようなリゾルバーを作成したい場合は、AWS AmplifyのGraphQL Transformという機能を利用して、自力でスキーマファイルからリゾルバーを生成するロジックを書く必要がある。
公式ドキュメント:GraphQL Transform - AWS Amplify
前述の通り、AWS Amplifyを使うならマネジメントコンソールからバックエンドの設定を調整するのは避けたい。しかし現状AWS AmplifyでDynamoDBのインデックスを作成するような設定項目がないため、自力でCloudFormationの設定を書く必要がある。
$ amplify push
コマンドにて生成されるamplify/backend/api/<プロジェクト名>/cloudformation-template.json
にバックエンドの詳細な設定を書くことができるので、ここでDynamoDBのGSI・LSIの設定を書くことになる。
AppSyncにはクライアントの認証タイプが4つ存在する。
このうち、Amazon Cognito User Pool
を選択することで、Cognitoで認証したユーザーに対してのみ呼び出しを許可することができる。また、AppSyncのスキーマに@aws_auth
ディレクティブをつけることで、特定のQuery・Mutationに制限をかけたり、許可したりすることができる。
(@aws_auth
をつけたQuery・Mutationが許可になるか拒否になるかはSettingsのDefault action
の設定による)
@aws_auth
ディレクティブでは、Cognitoの特定のグループにログイン中のユーザーが属しているかで許可・拒否ができたり、リゾルバー中で$context.identity
でログイン中のユーザーの情報や所属グループ情報を取ってきて利用することができる。
しかし、Amazon Cognito User Pool
を選択した場合、未ログイン状態でAPIを呼び出すことはできない。
未認証でAppSyncのAPIを呼び出したり、さらにログイン中のユーザーに対して細かい権限管理を行いたい場合は認証タイプをAWS Identity and Access Management (IAM)
にする。
認証タイプをAWS Identity and Access Management (IAM)
にすることで、クライアントにはCognitoのIdentity Poolで指定されている認証済みクライアントに割り当てられるロール(Auth Role)と未認証のクライアントに割り当てられるロール(Unauth Role)がログイン状態に応じて割り当てられる。
未認証状態ではユーザーを識別する術が無いためUnauth Roleが割り当てられるが、認証済みのクライアントにはCognitoユーザープール上でユーザーが属するグループごとにロールを分けることができる。
本番環境と開発環境を分けてバックエンドを構築してデプロイするには、multienvバージョンのAWS Amplifyを利用する。まだベータ版なので今後仕様が変更になる可能性がある。
$ npm install -g @aws-amplify/cli@multienv
公式ドキュメント:Multiple environments and team workflows (beta) - AWS Amplify
ChatQL: An AWS AppSync Chat Starter App written in Angular
AWSの公式サンプルのChatQLでは、$ amplify push
するとDymamoDBに複数のテーブルが生成される。
NoSQL設計ベストプラクティス的には「優れた設計のアプリケーションで必要なテーブルは 1 つのみ」であり、ソリューションアーキテクトの方的には一つのテーブルで設計することがベストプラクティスとのこと。
ただし、あくまでも基本であり、必要に応じてテーブルを分けても問題ない。
こちらはAWS Amplify/AWS AppSync/Amazon Cognito/Amazon DynamoDB等について調査してわからなかったことを目黒のAWS Loft TokyoのAsk An Expertブースにて質問して、私が理解できた範囲での内容となります。
各項目についてこれから具体的にサンプルアプリケーションを立ち上げて検証していく過程で誤り等を発見し次第訂正していきます。