概要
タイトルの通りですが、AWSのCloud9でAmplifyのチュートリアルをやってみたので、その内容・手順を投稿します。
Amplifyとは何者か?わかっていなかったのですが、このチュートリアルを通して概要が理解できたため、公式のチュートリアルはさすが良質な教材でした。
具体的には以下を実施します。
このチュートリアルでは「Todoアプリ」を作成します。
Todoアプリを通して、Amplifyでのユーザー認証、バックエンドにあるDynamoDBにGraphQL APIを使用し、アイテムを保存および取得することが出来るようになります。
チュートリアルでの使用するプログラミング言語はいくつか用意させれているようですが、本投稿ではReactを選択してします。
作業時間1時間ほどで実施できます。最終的には以下の「Todoアプリ」が出来上がります。
Create TodoボタンでNameとDescriptionに入力したTodoが登録され、画面下部に表示されます。
Amplifyで用意された認証画面でユーザ作成やユーザ認証が出来るようになります。
それでは、始めます。
前提条件
使用するCloud9はほぼデフォルト設定で使用できるのですが、以下だけ手動で変更しています。
- t2.medium 以上
- ディスク30GB 以上
1つ目は、メモリがある程度必要になるので、インスタントタイプにt2.mediumを選択。
2つ目は、Cloud9でよくあることなのですが、初期のディスク容量が10GBしかないので今回は30GBに増設しています。(手順は割愛しますが、EC2のディスクメニューから行います)
チュートリアル上に書かれていますが、使用するツールのバージョンが以下のバージョン以降である必要があるため、開始する前に次のものがインストールされていることを確認します。
- Node.js v14.x 以降
- npm v6.14.4 以降
- git v2.14.1 以降
具体的には、それぞれ以下のコマンドで確認できます。(Cloud9の作成の時に古いOSを指定していなければ新しいバージョンのものがインストールされているので特に意識しなくても大丈夫です)
- node -v
- npm -v
- git -v
参考書籍
Amplifyの知識の定着と基本的知識の補完に最適。
AWS Amplify Studioではじめるフロントエンド+バックエンド統合開発
Amplifyの日本語専門書としては現時点で唯一の専門書なのでAmplifyをやる上で参考書としていつも手元に置いておいてほしい一冊です。
結果
最初に結論です。
実施内容は、いくつかのコマンド実行と 2つのファイル修正(index.js/App.js) だけになります。
これだけでCloud9上にAmplifyを使ったReactプロジェクトが作成されます。
コマンド一覧
npm install -g @aws-amplify/cli
amplify configure
# Amplifyの設定コマンド。コマンド実行中にAWSコンソール上でのIAMユーザ作成が必要なります
npx create-react-app react-amplified-XXXX
# reactの雛形プロジェクト作成コマンド。後続のコマンド実行の中で「react-amplified-XXXX」を使ってS3バケットが作成されるため、重複しないように「XXXX」等少し変更しておくことをおすすめします
cd react-amplified-XXXX
amplify init
# Amplifyプロジェクト作成コマンド。
npm install aws-amplify
# Amplify Frameworkライブラリインストールコマンド。コマンド実行後、src/index.jsを開きAmplifyのインポート文を追加します
amplify add api
# AmplifyにGraphQL APIを追加するコマンド。
amplify push
# 追加したAPIをクラウド上のバックエンドAWSリソースに同期するコマンド。
# コマンド実行後、src/App.jsを開きGraphQL APIを使用したコードに置き換えます
amplify add auth
# Amplifyに認証を追加するコマンド。
amplify push
# 追加した認証をクラウド上のバックエンドAWSリソースに同期するコマンド。
npm install @aws-amplify/ui-react
# Amplify UIライブラリインストールコマンド。コマンド実行後、src/App.jsを開き認証コンポーネントの組み込みを行います
amplify add hosting
# Amplifyにホスティング環境を追加するコマンド。
amplify publish
# 追加したホスティング環境にReactプロジェクトを公開する。
詳細な説明は割愛しますが、以下が簡単な手順概略になります。
- Amplify CLI(aws-amplify/cli)インストール
- amplify configureコマンドによるシステム設定
- reactの雛形プロジェクト作成
- amplify initコマンドによるAmplifyプロジェクトの動作設定
- Amplify Framework(aws-amplify) や aws-amplify/ui-react といったreactライブラリのインストール
- amplify add XXXコマンドによる機能(認証やGraphQL API、ホスティングなど)追加
- amplify pushコマンドでCloud9上で設定した内容をバックエンド(のAWSリソース 例えばCognito、DynamoDBなど)に反映
- amplify publishコマンドでホスティング環境にデプロイ
赤字はAmplifyのポイントとなるコマンドです。次のAmplify全体概念図で説明します。
Amplify全体概念図
自分なりに解釈した結果を図にすると以下のイメージになると思います。
- Amplifyを使用する上で、Amplify CLIとAmplify Frameworkの2つをコマンドでインストールします。
- Amplify CLI:Amplifyプロジェクトの作成やAmplifyの各機能(認証とかAPIとか。Amplifyの用語ではカテゴリと呼ぶ)のインストール、各機能のバックエンドへの反映を行うAmplifyの専用コマンド群です。
- Amplify Framework:Amplifyのカテゴリを使用するためのクライアントライブラリ(今回は後述のindex.jsやApp.jsで使用するJavaScriptのクライアントライブラリです)
- この2つを意識しないと非常に混乱します。
- 基本的なAmplifyの操作方法として、Cloud9上のクライアント環境でAWS側のバックエンドサービスの設定含めて完結させる(上記概念図の左側の実線部)ため、上記概念図のAmplifyより右側の点線部は意識しません。(もちろんAWSコンソール上から意識して確認することは可能です)
- 後述のAmplifyのプロジェクトフォルダ内のamplifyというフォルダにバックエンドの定義が保存されます
修正後index.jsファイル
Amplify用のimportを追加し最終的には以下のファイルになります。
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Amplify } from 'aws-amplify'; // Amplify Framework の読み込み
import awsExports from './aws-exports'; // バックエンド設定の読み込み
Amplify.configure(awsExports); // Amplify Frameworkにバックエンドの設定を登録
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
修正後App.jsファイル
Amplify用のimportやTodoアプリの実装(認証やGraphQLによるDynamoDBアクセス)を追加し最終的には以下のファイルになります。
/* src/App.js */
import React, { useEffect, useState } from 'react'
import { Amplify, API, graphqlOperation } from 'aws-amplify'
import { createTodo } from './graphql/mutations'
import { listTodos } from './graphql/queries'
import { withAuthenticator, Button, Heading } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
import awsExports from "./aws-exports";
Amplify.configure(awsExports);
const initialState = { name: '', description: '' }
const App = ({ signOut, user }) => {
const [formState, setFormState] = useState(initialState)
const [todos, setTodos] = useState([])
useEffect(() => {
fetchTodos()
}, [])
function setInput(key, value) {
setFormState({ ...formState, [key]: value })
}
async function fetchTodos() {
try {
const todoData = await API.graphql(graphqlOperation(listTodos))
const todos = todoData.data.listTodos.items
setTodos(todos)
} catch (err) { console.log('error fetching todos') }
}
async function addTodo() {
try {
if (!formState.name || !formState.description) return
const todo = { ...formState }
setTodos([...todos, todo])
setFormState(initialState)
await API.graphql(graphqlOperation(createTodo, {input: todo}))
} catch (err) {
console.log('error creating todo:', err)
}
}
return (
<div style={styles.container}>
<Heading level={1}>Hello {user.username}</Heading>
<Button onClick={signOut} style={styles.button}>Sign out</Button>
<h2>Amplify Todos</h2>
<input
onChange={event => setInput('name', event.target.value)}
style={styles.input}
value={formState.name}
placeholder="Name"
/>
<input
onChange={event => setInput('description', event.target.value)}
style={styles.input}
value={formState.description}
placeholder="Description"
/>
<button style={styles.button} onClick={addTodo}>Create Todo</button>
{
todos.map((todo, index) => (
<div key={todo.id ? todo.id : index} style={styles.todo}>
<p style={styles.todoName}>{todo.name}</p>
<p style={styles.todoDescription}>{todo.description}</p>
</div>
))
}
</div>
)
}
const styles = {
container: { width: 400, margin: '0 auto', display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: 20 },
todo: { marginBottom: 15 },
input: { border: 'none', backgroundColor: '#ddd', marginBottom: 10, padding: 8, fontSize: 18 },
todoName: { fontSize: 20, fontWeight: 'bold' },
todoDescription: { marginBottom: 0 },
button: { backgroundColor: 'black', color: 'white', outline: 'none', fontSize: 18, padding: '12px 0px' }
}
export default withAuthenticator(App);
Cloud9のReactプロジェクト フォルダ/ファイルリスト
最終的な成果物は以下のようになります。
(ビルドファイルなど自動的に作成される一部のファイルは割愛しています)
$ ls -lRt react-amplified-XXXX/
react-amplified-XXXX/:
total 2372
drwxrwxr-x 6 ec2-user ec2-user 143 Dec 17 01:33 amplify
-rw-rw-r-- 1 ec2-user ec2-user 886 Dec 16 05:52 package.json
-rw-rw-r-- 1 ec2-user ec2-user 2360099 Dec 16 05:52 package-lock.json
drwxrwxr-x 3 ec2-user ec2-user 187 Dec 16 05:25 src
drwxrwxr-x 2 ec2-user ec2-user 120 Dec 16 04:49 public
-rw-rw-r-- 1 ec2-user ec2-user 3359 Dec 16 04:49 README.md
react-amplified-XXXX/amplify:
total 12
-rw-rw-r-- 1 ec2-user ec2-user 1010 Dec 17 01:35 team-provider-info.json
drwxrwxr-x 7 ec2-user ec2-user 151 Dec 16 05:49 backend
-rw-rw-r-- 1 ec2-user ec2-user 1834 Dec 16 05:06 cli.json
drwxrwxr-x 2 ec2-user ec2-user 76 Dec 16 05:05 hooks
-rw-rw-r-- 1 ec2-user ec2-user 393 Dec 16 05:05 README.md
react-amplified-XXXX/amplify/backend:
total 12
-rw-rw-r-- 1 ec2-user ec2-user 3806 Dec 17 01:33 amplify-meta.json
-rw-rw-r-- 1 ec2-user ec2-user 1206 Dec 16 05:45 backend-config.json
drwxrwxr-x 3 ec2-user ec2-user 36 Dec 16 05:45 auth
drwxrwxr-x 3 ec2-user ec2-user 28 Dec 16 05:30 hosting
drwxrwxr-x 3 ec2-user ec2-user 28 Dec 16 05:16 api
drwxrwxr-x 2 ec2-user ec2-user 50 Dec 16 05:06 types
drwxrwxr-x 3 ec2-user ec2-user 19 Dec 16 05:06 awscloudformation
-rw-rw-r-- 1 ec2-user ec2-user 135 Dec 16 05:05 tags.json
react-amplified-XXXX/amplify/backend/auth:
total 0
drwxrwxr-x 3 ec2-user ec2-user 42 Dec 16 05:45 reactamplified8ea01234
react-amplified-XXXX/amplify/backend/auth/reactamplified8ea01234:
total 4
-rw-rw-r-- 1 ec2-user ec2-user 1454 Dec 16 05:45 cli-inputs.json
drwxrwxr-x 2 ec2-user ec2-user 88 Dec 16 05:45 build
react-amplified-XXXX/amplify/backend/auth/reactamplified8ea01234/build:
total 20
-rw-rw-r-- 1 ec2-user ec2-user 1548 Dec 17 01:33 parameters.json
-rw-rw-r-- 1 ec2-user ec2-user 13498 Dec 17 01:33 reactamplified8ea01234-cloudformation-template.json
react-amplified-XXXX/amplify/backend/hosting:
total 0
drwxrwxr-x 2 ec2-user ec2-user 42 Dec 16 05:30 amplifyhosting
react-amplified-XXXX/amplify/backend/hosting/amplifyhosting:
total 4
-rw-rw-r-- 1 ec2-user ec2-user 757 Dec 16 05:31 amplifyhosting-template.json
react-amplified-XXXX/amplify/backend/api:
total 0
drwxrwxr-x 5 ec2-user ec2-user 145 Dec 16 05:17 reactamplified
react-amplified-XXXX/amplify/backend/api/reactamplified:
total 16
-rw-rw-r-- 1 ec2-user ec2-user 131 Dec 17 01:33 parameters.json
drwxrwxr-x 5 ec2-user ec2-user 135 Dec 17 01:33 build
-rw-rw-r-- 1 ec2-user ec2-user 196 Dec 16 05:16 cli-inputs.json
-rw-rw-r-- 1 ec2-user ec2-user 363 Dec 16 05:16 schema.graphql
drwxrwxr-x 2 ec2-user ec2-user 34 Dec 16 05:16 stacks
-rw-rw-r-- 1 ec2-user ec2-user 54 Dec 16 05:16 transform.conf.json
drwxrwxr-x 2 ec2-user ec2-user 23 Dec 16 05:16 resolvers
react-amplified-XXXX/amplify/backend/api/reactamplified/build:
total 24
-rw-rw-r-- 1 ec2-user ec2-user 10494 Dec 17 01:33 cloudformation-template.json
drwxrwxr-x 2 ec2-user ec2-user 6 Dec 17 01:33 functions
-rw-rw-r-- 1 ec2-user ec2-user 303 Dec 17 01:33 parameters.json
drwxrwxr-x 2 ec2-user ec2-user 51 Dec 17 01:33 stacks
drwxrwxr-x 2 ec2-user ec2-user 4096 Dec 17 01:33 resolvers
-rw-rw-r-- 1 ec2-user ec2-user 3748 Dec 17 01:33 schema.graphql
react-amplified-XXXX/amplify/backend/api/reactamplified/build/functions:
total 0
react-amplified-XXXX/amplify/backend/api/reactamplified/build/stacks:
total 40
-rw-rw-r-- 1 ec2-user ec2-user 1493 Dec 17 01:33 CustomResources.json
-rw-rw-r-- 1 ec2-user ec2-user 35961 Dec 17 01:33 Todo.json
react-amplified-XXXX/amplify/backend/api/reactamplified/build/resolvers:
total 108
-rw-rw-r-- 1 ec2-user ec2-user 475 Dec 17 01:33 Mutation.createTodo.init.1.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 210 Dec 17 01:33 Mutation.createTodo.postAuth.1.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 2238 Dec 17 01:33 Mutation.createTodo.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 222 Dec 17 01:33 Mutation.createTodo.res.vtl
-rw-rw-r-- 1 ec2-user ec2-user 210 Dec 17 01:33 Mutation.deleteTodo.postAuth.1.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 1847 Dec 17 01:33 Mutation.deleteTodo.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 222 Dec 17 01:33 Mutation.deleteTodo.res.vtl
-rw-rw-r-- 1 ec2-user ec2-user 350 Dec 17 01:33 Mutation.updateTodo.init.1.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 210 Dec 17 01:33 Mutation.updateTodo.postAuth.1.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 4371 Dec 17 01:33 Mutation.updateTodo.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 222 Dec 17 01:33 Mutation.updateTodo.res.vtl
-rw-rw-r-- 1 ec2-user ec2-user 210 Dec 17 01:33 Query.getTodo.postAuth.1.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 1208 Dec 17 01:33 Query.getTodo.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 381 Dec 17 01:33 Query.getTodo.res.vtl
-rw-rw-r-- 1 ec2-user ec2-user 210 Dec 17 01:33 Query.listTodos.postAuth.1.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 1798 Dec 17 01:33 Query.listTodos.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 169 Dec 17 01:33 Query.listTodos.res.vtl
-rw-rw-r-- 1 ec2-user ec2-user 210 Dec 17 01:33 Subscription.onCreateTodo.postAuth.1.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 148 Dec 17 01:33 Subscription.onCreateTodo.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 249 Dec 17 01:33 Subscription.onCreateTodo.res.vtl
-rw-rw-r-- 1 ec2-user ec2-user 210 Dec 17 01:33 Subscription.onDeleteTodo.postAuth.1.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 148 Dec 17 01:33 Subscription.onDeleteTodo.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 249 Dec 17 01:33 Subscription.onDeleteTodo.res.vtl
-rw-rw-r-- 1 ec2-user ec2-user 210 Dec 17 01:33 Subscription.onUpdateTodo.postAuth.1.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 148 Dec 17 01:33 Subscription.onUpdateTodo.req.vtl
-rw-rw-r-- 1 ec2-user ec2-user 249 Dec 17 01:33 Subscription.onUpdateTodo.res.vtl
react-amplified-XXXX/amplify/backend/api/reactamplified/stacks:
total 4
-rw-rw-r-- 1 ec2-user ec2-user 1470 Dec 16 05:16 CustomResources.json
react-amplified-XXXX/amplify/backend/api/reactamplified/resolvers:
total 4
-rw-rw-r-- 1 ec2-user ec2-user 298 Dec 16 05:16 README.md
react-amplified-XXXX/amplify/backend/types:
total 4
-rw-rw-r-- 1 ec2-user ec2-user 584 Dec 17 01:33 amplify-dependent-resources-ref.d.ts
react-amplified-XXXX/amplify/backend/awscloudformation:
total 0
drwxrwxr-x 6 ec2-user ec2-user 107 Dec 16 05:45 build
react-amplified-XXXX/amplify/backend/awscloudformation/build:
total 16
-rw-rw-r-- 1 ec2-user ec2-user 14572 Dec 16 05:49 root-cloudformation-stack.json
drwxrwxr-x 3 ec2-user ec2-user 36 Dec 16 05:45 auth
drwxrwxr-x 3 ec2-user ec2-user 28 Dec 16 05:31 hosting
drwxrwxr-x 3 ec2-user ec2-user 19 Dec 16 05:21 awscloudformation
drwxrwxr-x 3 ec2-user ec2-user 28 Dec 16 05:21 api
react-amplified-XXXX/amplify/backend/awscloudformation/build/auth:
total 0
drwxrwxr-x 3 ec2-user ec2-user 19 Dec 16 05:45 reactamplified8ea01234
react-amplified-XXXX/amplify/backend/awscloudformation/build/auth/reactamplified8ea01234:
total 0
drwxrwxr-x 2 ec2-user ec2-user 65 Dec 16 05:45 build
react-amplified-XXXX/amplify/backend/awscloudformation/build/auth/reactamplified8ea01234/build:
total 16
-rw-rw-r-- 1 ec2-user ec2-user 13582 Dec 16 05:45 reactamplified8ea01234-cloudformation-template.json
react-amplified-XXXX/amplify/backend/awscloudformation/build/hosting:
total 0
drwxrwxr-x 2 ec2-user ec2-user 42 Dec 16 05:31 amplifyhosting
react-amplified-XXXX/amplify/backend/awscloudformation/build/hosting/amplifyhosting:
total 4
-rw-rw-r-- 1 ec2-user ec2-user 757 Dec 16 05:31 amplifyhosting-template.json
react-amplified-XXXX/amplify/backend/awscloudformation/build/awscloudformation:
total 0
drwxrwxr-x 2 ec2-user ec2-user 44 Dec 16 05:21 build
react-amplified-XXXX/amplify/backend/awscloudformation/build/awscloudformation/build:
total 16
-rw-rw-r-- 1 ec2-user ec2-user 14572 Dec 16 05:45 root-cloudformation-stack.json
react-amplified-XXXX/amplify/backend/awscloudformation/build/api:
total 0
drwxrwxr-x 3 ec2-user ec2-user 19 Dec 16 05:21 reactamplified
react-amplified-XXXX/amplify/backend/awscloudformation/build/api/reactamplified:
total 0
drwxrwxr-x 2 ec2-user ec2-user 42 Dec 16 05:21 build
react-amplified-XXXX/amplify/backend/awscloudformation/build/api/reactamplified/build:
total 8
-rw-rw-r-- 1 ec2-user ec2-user 7761 Dec 16 05:21 cloudformation-template.json
react-amplified-XXXX/amplify/hooks:
total 12
-rw-r--r-- 1 ec2-user ec2-user 678 Dec 16 05:05 post-push.sh.sample
-rw-r--r-- 1 ec2-user ec2-user 833 Dec 16 05:05 pre-push.js.sample
-rw-r--r-- 1 ec2-user ec2-user 412 Dec 16 05:05 README.md
react-amplified-XXXX/src:
total 36
-rw-rw-r-- 1 ec2-user ec2-user 2947 Dec 17 01:33 App.js
-rw-rw-r-- 1 ec2-user ec2-user 1207 Dec 16 05:49 aws-exports.js
drwxrwxr-x 2 ec2-user ec2-user 87 Dec 16 05:25 graphql
-rw-rw-r-- 1 ec2-user ec2-user 645 Dec 16 05:13 index.js
-rw-rw-r-- 1 ec2-user ec2-user 2632 Dec 16 04:49 logo.svg
-rw-rw-r-- 1 ec2-user ec2-user 362 Dec 16 04:49 reportWebVitals.js
-rw-rw-r-- 1 ec2-user ec2-user 241 Dec 16 04:49 setupTests.js
-rw-rw-r-- 1 ec2-user ec2-user 564 Dec 16 04:49 App.css
-rw-rw-r-- 1 ec2-user ec2-user 246 Dec 16 04:49 App.test.js
-rw-rw-r-- 1 ec2-user ec2-user 366 Dec 16 04:49 index.css
react-amplified-XXXX/src/graphql:
total 92
-rw-rw-r-- 1 ec2-user ec2-user 790 Dec 16 05:25 subscriptions.js
-rw-rw-r-- 1 ec2-user ec2-user 916 Dec 16 05:25 mutations.js
-rw-rw-r-- 1 ec2-user ec2-user 596 Dec 16 05:25 queries.js
-rw-rw-r-- 1 ec2-user ec2-user 79072 Dec 16 05:25 schema.json
react-amplified-XXXX/public:
total 36
-rw-rw-r-- 1 ec2-user ec2-user 3870 Dec 16 04:49 favicon.ico
-rw-rw-r-- 1 ec2-user ec2-user 1721 Dec 16 04:49 index.html
-rw-rw-r-- 1 ec2-user ec2-user 5347 Dec 16 04:49 logo192.png
-rw-rw-r-- 1 ec2-user ec2-user 9664 Dec 16 04:49 logo512.png
-rw-rw-r-- 1 ec2-user ec2-user 492 Dec 16 04:49 manifest.json
-rw-rw-r-- 1 ec2-user ec2-user 67 Dec 16 04:49 robots.txt
詳細は割愛しますが、要点としては以下が挙げられます。
-
amplifyというフォルダにバックエンドの定義が保存されます
- チュートリアルでは、GraphQL API や認証などの機能をしているため、amplifyフォルダ配下に、バックエンドスタックを定義するコードとしてのインフラストラクチャテンプレートが保存されます
- Amplifyで作成するサービスの設定を保持するaws-exports.jsというファイルがsrcディレクトリに作成されます
/* eslint-disable */
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.
const awsmobile = {
"aws_project_region": "ap-northeast-1",
"aws_appsync_graphqlEndpoint": "https://XXXXXXXXXXXXX.appsync-api.ap-northeast-1.amazonaws.com/graphql",
"aws_appsync_region": "ap-northeast-1",
"aws_appsync_authenticationType": "API_KEY",
"aws_appsync_apiKey": "***************************",
"aws_cognito_identity_pool_id": "ap-northeast-1:XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX",
"aws_cognito_region": "ap-northeast-1",
"aws_user_pools_id": "ap-northeast-1_XXXXXXX",
"aws_user_pools_web_client_id": "***************************",
"oauth": {},
"aws_cognito_username_attributes": [],
"aws_cognito_social_providers": [],
"aws_cognito_signup_attributes": [
"EMAIL"
],
"aws_cognito_mfa_configuration": "OFF",
"aws_cognito_mfa_types": [
"SMS"
],
"aws_cognito_password_protection_settings": {
"passwordPolicyMinLength": 8,
"passwordPolicyCharacters": []
},
"aws_cognito_verification_mechanisms": [
"EMAIL"
]
};
export default awsmobile;
このファイルに記録されるのは、Amplifyで作成するサービスの設定ということですが、DynamoDBの情報等はaws-exports.jsに記録されないのでフロントエンドからアクセスするバックエンドサービスのエンドポイントの設定内容が記録されるファイルかな。という印象です。
手順詳細
それではここからはチュートリアルのページに沿った手順詳細を説明してきます。
Install and configure the Amplify CLI
まずは Amplify CLI のインストールと設定です。
公式ページは以下のページ。
Amplify CLI のインストールはコマンド実行だけなので簡単です。
以下のコマンドを実行します。
UserXXXXXXX:~/environment $ npm install -g @aws-amplify/cli
added 26 packages, and audited 27 packages in 17s
7 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
UserXXXXXXX:~/environment $
次のAmplify CLI の設定はコマンド実行とともに少しAWS コンソール上での操作が必要です。
コマンド実行中に手順に従って、AWSコンソール上でのIAMユーザ作成を行います。
amplify configure コマンド実行すると以下のようになります。
本来、自動的にブラウザが作成されAWSコンソールへのログインやIAMユーザが自動的に作成される仕組みのようですが、Cloud9上でブラウザが出来ないため一度エラーのメッセージが表示されますが、表示されているURLを自分でブラウザに貼り付けて操作を続ければ設定は問題なく実行できます。
UserXXXXXXX:~/environment $ 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
🛑 spawn xdg-open ENOENT
Resolution: Please report this issue at https://github.com/aws-amplify/amplify-cli/issues and include the project identifier from: 'amplify diagnose --send-report'
Learn more at: https://docs.amplify.aws/cli/project/troubleshooting/
Session Identifier: ff133f1-a44c-409f-mod3-81297bd8f64a5a
Specify the AWS Region
? region: ap-northeast-1
Specify the username of the new IAM user:
? user name: amplify-19IB4
Complete the user creation using the AWS console
https://console.aws.amazon.com/iam/home?region=ap-northeast-1#/users$new?step=final&accessKey&userNames=amplify-19IB4&permissionType=policies&policies=arn:aws:iam::aws:policy%2FAdministratorAccess-Amplify
Press Enter to continue
🛑 spawn xdg-open ENOENT
Resolution: Please report this issue at https://github.com/aws-amplify/amplify-cli/issues and include the project identifier from: 'amplify diagnose --send-report'
Learn more at: https://docs.amplify.aws/cli/project/troubleshooting/
Session Identifier: ff133f1-a44c-409f-mod3-81297bd8f64a5a
Enter the access key of the newly created user:
? accessKeyId: ********************
? secretAccessKey: ****************************************
This would update/create the AWS Profile in your local machine
? Profile Name: default
Successfully set up the new user.
UserXXXXXXX:~/environment $
region選択やIAMのユーザ名(user name)などいくつか対話側のやり取りがあるので、適切なものを選択します。IAMのユーザ名は何でも良い(上記はデフォルトのままです)のですが、このユーザが必要になるので、ユーザ名決定後表示されている以下のURLをAWSコンソールを開いているブラウザに貼り付けてユーザ作成を行います。
https://console.aws.amazon.com/iam/home?region=ap-northeast-1#/users$new?step=final&accessKey&userNames=amplify-19IB4&permissionType=policies&policies=arn:aws:iam::aws:policy%2FAdministratorAccess-Amplify
重要なのはURLの最後についているAdministratorAccess-AmplifyポリシーがAmplifyには必要ということです。
URL貼り付け後の画面上でも確認できます。
問題なければそのままAWSコンソール上での画面操作でユーザ作成を行い、ユーザ作成完了画面に表示されているaccessKeyId/secretAccessKeyをコマンド実行したターミナルに貼り付けます。(上記のコマンド結果で********************でマスクされている部分です)
この部分はチュートリアル上、動画でも解説されているので必要であれば動画で確認してみてください。以下の部分になります。
Create a new React App
次の手順に移ります。次は、Reactの雛形プロジェクト作成です。
公式ページは以下のページ。
これはAmplifyとは関係のないReactの雛形プロジェクト作成のため、以下のコマンドを実行するだけです。react-amplified-0001部分がプロジェクト名になり、任意の名称に変更可能です。S3バケット名の一部として使用されるため、ユニークになるように自分の分かりやすい名称に変更することをオススメします。
UserXXXXXXX:~/environment $ npx create-react-app react-amplified-0001
Need to install the following packages:
create-react-app@5.0.1
Ok to proceed? (y)
npm WARN deprecated tar@2.2.2: This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.
Creating a new React app in /home/ec2-user/environment/react-amplified-0001.
Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template...
added 1395 packages in 1m
214 packages are looking for funding
run `npm fund` for details
Initialized a git repository.
Installing template dependencies using npm...
added 71 packages in 10s
226 packages are looking for funding
run `npm fund` for details
Removing template package using npm...
removed 1 package, and audited 1466 packages in 3s
226 packages are looking for funding
run `npm fund` for details
6 high severity vulnerabilities
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
Created git commit.
Success! Created react-amplified-0001 at /home/ec2-user/environment/react-amplified-0001
Inside that directory, you can run several commands:
npm start
Starts the development server.
npm run build
Bundles the app into static files for production.
npm test
Starts the test runner.
npm run eject
Removes this tool and copies build dependencies, configuration files
and scripts into the app directory. If you do this, you can’t go back!
We suggest that you begin by typing:
cd react-amplified-0001
npm start
Happy hacking!
UserXXXXXXX:~/environment $
無事に雛形プロジェクトの作成に成功したら、プロジェクトのルートフォルダに移動します。
UserXXXXXXX:~/environment $ cd react-amplified-0001
UserXXXXXXX:~/environment/react-amplified-0001 (master) $
Initialize a new backend
では、いよいよAmplify独自のAmplifyの設定手順に移ります。
公式ページは以下のページ。
amplify initコマンドでAmplifyの設定を行います。
基本的に自動実行でプロジェクトの情報(NameやEnvironment、Default editorなど)が設定されるためそのまま継続します。
最後にCloudFormationを使ってIAMユーザはS3バケットが作成されていることがわかると思います。(万が一、S3バケットの名前がユニークでなかった場合、ここで失敗します。Reactの雛形プロジェクト作成からやり直しましょう。。。)
UserXXXXXXX:~/environment/react-amplified-0001 (master) $ amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project reactamplified0001
The following configuration will be applied:
Project information
| Name: reactamplified0001
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: react
| Source Directory Path: src
| Distribution Directory Path: build
| Build Command: npm run-script build
| Start Command: npm run-script start
? Initialize the project with the above configuration? Yes
Using default provider awscloudformation
? Select the authentication method you want to use: AWS profile
For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html
? Please choose the profile you want to use default
Adding backend environment dev to AWS Amplify app: d123qswk5htmod
Deployment completed.
Deployed root stack reactamplified0001 [ ======================================== ] 4/4
amplify-reactamplified0001-de… AWS::CloudFormation::Stack CREATE_COMPLETE Sat Dec 17 2022 02:18:39…
UnauthRole AWS::IAM::Role CREATE_COMPLETE Sat Dec 17 2022 02:18:37…
DeploymentBucket AWS::S3::Bucket CREATE_COMPLETE Sat Dec 17 2022 02:18:27…
AuthRole AWS::IAM::Role CREATE_COMPLETE Sat Dec 17 2022 02:18:36…
✔ Help improve Amplify CLI by sharing non sensitive configurations on failures (y/N) · no
Deployment bucket fetched.
✔ Initialized provider successfully.
✅ Initialized your environment successfully.
Your project has been successfully initialized and connected to the cloud!
Some next steps:
"amplify status" will show you what you've added already and if it's locally configured or deployed
"amplify add <category>" will allow you to add features like user login or a backend API
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify console" to open the Amplify Console and view your project status
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
Pro tip:
Try "amplify add api" to create a backend API and then "amplify push" to deploy everything
UserXXXXXXX:~/environment/react-amplified-0001 (master) $
コマンド実行結果の以下に表示されている通り、Amplifyでは以下のコマンド群で操作することになります。
Some next steps:
"amplify status" will show you what you've added already and if it's locally configured or deployed
"amplify add <category>" will allow you to add features like user login or a backend API
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify console" to open the Amplify Console and view your project status
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
今回のチュートリアルでは、amplify statusとamplify console以外は実行する手順になっているので後の手順で試すことができます。
amplify statusは手順にはありませんが、Amplifyの状態を確認するコマンドのため、いつ実行しても問題ありません。
amplify consoleはブラウザでAWSコンソールを開くコマンドなのでCloud9上では実行しても正しく動作しません。(自身のブラウザ操作でAWSコンソールのAmplifyメニューを表示すれば確認可能です)
Install Amplify Libraries
次の手順はAmplifyのライブラリインストールになります。
公式ページは以下のページ。
手順はnpm install aws-amplifyコマンドを実行するだけになっています。
一部のライブラリが古いせいかセキュリティ警告が出るので理解して使いましょう。。。(^^;)
UserXXXXXXX:~/environment/react-amplified-0001 (master) $ npm install aws-amplify
npm WARN deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.3.2: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated uglify-es@3.3.9: support for ECMAScript is superseded by `uglify-js` as of v3.13.0
npm WARN deprecated @aws-sdk/util-base64-browser@3.6.1: The package @aws-sdk/util-base64-browser has been renamed to @aws-sdk/util-base64. Please install the renamed package.
npm WARN deprecated @aws-sdk/util-base64-node@3.6.1: The package @aws-sdk/util-base64-node has been renamed to @aws-sdk/util-base64. Please install the renamed package.
npm WARN deprecated @aws-sdk/eventstream-marshaller@3.6.1: The package @aws-sdk/eventstream-marshaller has been renamed to @aws-sdk/eventstream-codec. Please install the renamed package.
npm WARN deprecated @aws-sdk/util-base64-browser@3.186.0: The package @aws-sdk/util-base64-browser has been renamed to @aws-sdk/util-base64. Please install the renamed package.
npm WARN deprecated @aws-sdk/util-base64-node@3.186.0: The package @aws-sdk/util-base64-node has been renamed to @aws-sdk/util-base64. Please install the renamed package.
npm WARN deprecated @aws-sdk/util-base64-browser@3.186.0: The package @aws-sdk/util-base64-browser has been renamed to @aws-sdk/util-base64. Please install the renamed package.
npm WARN deprecated @aws-sdk/util-base64-node@3.186.0: The package @aws-sdk/util-base64-node has been renamed to @aws-sdk/util-base64. Please install the renamed package.
npm WARN deprecated @aws-sdk/util-base64-browser@3.186.0: The package @aws-sdk/util-base64-browser has been renamed to @aws-sdk/util-base64. Please install the renamed package.
npm WARN deprecated @aws-sdk/util-base64-node@3.186.0: The package @aws-sdk/util-base64-node has been renamed to @aws-sdk/util-base64. Please install the renamed package.
npm WARN deprecated @aws-sdk/util-base64-browser@3.186.0: The package @aws-sdk/util-base64-browser has been renamed to @aws-sdk/util-base64. Please install the renamed package.
npm WARN deprecated @aws-sdk/util-base64-browser@3.186.0: The package @aws-sdk/util-base64-browser has been renamed to @aws-sdk/util-base64. Please install the renamed package.
npm WARN deprecated @aws-sdk/util-base64-node@3.186.0: The package @aws-sdk/util-base64-node has been renamed to @aws-sdk/util-base64. Please install the renamed package.
npm WARN deprecated @aws-sdk/util-base64-node@3.186.0: The package @aws-sdk/util-base64-node has been renamed to @aws-sdk/util-base64. Please install the renamed package.
npm WARN deprecated @aws-sdk/util-base64-browser@3.186.0: The package @aws-sdk/util-base64-browser has been renamed to @aws-sdk/util-base64. Please install the renamed package.
npm WARN deprecated @aws-sdk/util-base64-node@3.186.0: The package @aws-sdk/util-base64-node has been renamed to @aws-sdk/util-base64. Please install the renamed package.
added 1125 packages, and audited 2591 packages in 1m
243 packages are looking for funding
run `npm fund` for details
6 high severity vulnerabilities
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
UserXXXXXXX:~/environment/react-amplified-0001 (master) $
Amplify Frameworkライブラリのインストールが完了すると、Amplifyの各機能(認証とかAPIとか。Amplifyの用語ではカテゴリと呼ぶ)を使用するためのクライアントライブラリを、Reactアプリで使用することができるようになるため、src/index.js ファイルに以下のimport文を追加します。
import { Amplify } from 'aws-amplify';
import awsExports from './aws-exports';
Amplify.configure(awsExports);
Connect API and database to the app
いよいよここからTodoアプリを作成するための手順に移ります。
最初はデータを保持するためのDynamoDBとDynamoDBアクセスのためのGraphQLの追加です。
公式ページは以下のページ。
具体的には、amplify add apiコマンドと、amplify pushコマンドで実行します。
まずはamplify add apiコマンドです。
UserXXXXXXX:~/environment/react-amplified-0001 (master) $ 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)
⚠️ WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules
✅ GraphQL schema compiled successfully.
Edit your schema at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema
✔ Do you want to edit the schema now? (Y/n) · yes
Couldn’t find selected code editor (Visual Studio Code) on your machine.
? Try opening with system-default editor instead? Yes
✅ Successfully added resource reactamplified0001 locally
✅ Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
🛑 spawn xdg-open ENOENT
Resolution: Please report this issue at https://github.com/aws-amplify/amplify-cli/issues and include the project identifier from: 'amplify diagnose --send-report'
Learn more at: https://docs.amplify.aws/cli/project/troubleshooting/
Session Identifier: c7e413414-173f-4663-modf-134134jiouoh
UserXXXXXXX:~/environment/react-amplified-0001 (master) $
特にこだわらなければデフォルトのままで大丈夫です。
このコマンドの中でTodoアプリのDynamoDB定義が自動作成されていることがわかると思います。
警告が出ている通りですが、WARNING: your GraphQL API currently allows publicであることを認識して使用しましょう。via an API Keyではありますが。
次は、amplify pushコマンドの実行です。
UserXXXXXXX:~/environment/react-amplified-0001 (master) $ amplify push
⠙ Fetching updates to backend environment: dev from the cloud.
⚠️ WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules
✅ GraphQL schema compiled successfully.
Edit your schema at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema
✔ Successfully pulled backend environment dev from the cloud.
⠹ Building resource api/reactamplified0001
⚠️ WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules
✅ GraphQL schema compiled successfully.
Edit your schema at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema
Current Environment: dev
┌──────────┬────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name │ Operation │ Provider plugin │
├──────────┼────────────────────┼───────────┼───────────────────┤
│ Api │ reactamplified0001 │ Create │ awscloudformation │
└──────────┴────────────────────┴───────────┴───────────────────┘
? Are you sure you want to continue? Yes
⚠️ WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules
✅ GraphQL schema compiled successfully.
Edit your schema at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema
⠦ Building resource api/reactamplified0001
⚠️ WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules
✅ GraphQL schema compiled successfully.
Edit your schema at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema
? 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
Deployment completed.
Deployed root stack reactamplified0001 [ ======================================== ] 2/2
amplify-reactamplified0001-de… AWS::CloudFormation::Stack UPDATE_COMPLETE Sat Dec 17 2022 02:30:08…
apireactamplified0001 AWS::CloudFormation::Stack CREATE_COMPLETE Sat Dec 17 2022 02:30:04…
Deployed api reactamplified0001 [ ======================================== ] 6/6
GraphQLAPI AWS::AppSync::GraphQLApi CREATE_COMPLETE Sat Dec 17 2022 02:26:40…
GraphQLAPIDefaultApiXXX123456… AWS::AppSync::ApiKey CREATE_COMPLETE Sat Dec 17 2022 02:26:44…
GraphQLAPITransformerSchema3C… AWS::AppSync::GraphQLSchema CREATE_COMPLETE Sat Dec 17 2022 02:27:46…
GraphQLAPIABCDS983766MOD AWS::AppSync::DataSource CREATE_COMPLETE Sat Dec 17 2022 02:26:45…
Todo AWS::CloudFormation::Stack CREATE_COMPLETE Sat Dec 17 2022 02:29:24…
CustomResourcesjson AWS::CloudFormation::Stack CREATE_COMPLETE Sat Dec 17 2022 02:29:38…
✔ Generated GraphQL operations successfully and saved at src/graphql
GraphQL endpoint: https://XXXXXXXXXXXXX.appsync-api.ap-northeast-1.amazonaws.com/graphql
GraphQL API KEY: ***************************
GraphQL transformer version: 2
UserXXXXXXX:~/environment/react-amplified-0001 (master) $
こちらもこだわらなければデフォルトのままで大丈夫です。
ここでも何回も警告が出ているので、WARNING: your GraphQL API currently allows publicであることを認識して使用しましょう。
コマンド実行の最後のGraphQL endpointと、API KEYが表示されるので認識しておきましょう。(上記のコマンド結果はもちろんマスクしています)
コマンド実行中の表示内容で確認できますが、amplify pushコマンドでCloudFormationによって必要なAWSのバックエンドサービスが作成されています。
つまり、amplify addコマンドでローカル環境(今回はCloud9上)のファイルにAWSリソース定義を行い、amplify pushコマンドでCloudFormationを使ってAWSリソースが作成される仕組みがAmplifyなのだと理解できます。
最後に上記2つのコマンド実行でDBの準備ができたので、Reactアプリに取り込みましょう。
編集ファイルはsrc/App.jsになります。
/* src/App.js */
import React, { useEffect, useState } from 'react'
import { Amplify, API, graphqlOperation } from 'aws-amplify'
import { createTodo } from './graphql/mutations'
import { listTodos } from './graphql/queries'
import awsExports from "./aws-exports";
Amplify.configure(awsExports);
const initialState = { name: '', description: '' }
const App = () => {
const [formState, setFormState] = useState(initialState)
const [todos, setTodos] = useState([])
useEffect(() => {
fetchTodos()
}, [])
function setInput(key, value) {
setFormState({ ...formState, [key]: value })
}
async function fetchTodos() {
try {
const todoData = await API.graphql(graphqlOperation(listTodos))
const todos = todoData.data.listTodos.items
setTodos(todos)
} catch (err) { console.log('error fetching todos') }
}
async function addTodo() {
try {
if (!formState.name || !formState.description) return
const todo = { ...formState }
setTodos([...todos, todo])
setFormState(initialState)
await API.graphql(graphqlOperation(createTodo, {input: todo}))
} catch (err) {
console.log('error creating todo:', err)
}
}
return (
<div style={styles.container}>
<h2>Amplify Todos</h2>
<input
onChange={event => setInput('name', event.target.value)}
style={styles.input}
value={formState.name}
placeholder="Name"
/>
<input
onChange={event => setInput('description', event.target.value)}
style={styles.input}
value={formState.description}
placeholder="Description"
/>
<button style={styles.button} onClick={addTodo}>Create Todo</button>
{
todos.map((todo, index) => (
<div key={todo.id ? todo.id : index} style={styles.todo}>
<p style={styles.todoName}>{todo.name}</p>
<p style={styles.todoDescription}>{todo.description}</p>
</div>
))
}
</div>
)
}
const styles = {
container: { width: 400, margin: '0 auto', display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: 20 },
todo: { marginBottom: 15 },
input: { border: 'none', backgroundColor: '#ddd', marginBottom: 10, padding: 8, fontSize: 18 },
todoName: { fontSize: 20, fontWeight: 'bold' },
todoDescription: { marginBottom: 0 },
button: { backgroundColor: 'black', color: 'white', outline: 'none', fontSize: 18, padding: '12px 0px' }
}
export default App
Add authentication
チュートリアルももう少しで完了です。次は認証機能を追加します。
公式ページは以下のページ。
手順としては1つ前の手順のDBの追加の時の同様で、amplify add authコマンドと、amplify pushコマンドで実行します。
まずはamplify add authコマンドです。
UserXXXXXXX:~/environment/react-amplified-0001 (master) $ amplify add auth
Using service: Cognito, provided by: awscloudformation
The current configured provider is Amazon Cognito.
Do you want to use the default authentication and security configuration? Default configuration
Warning: you will not be able to edit these selections.
How do you want users to be able to sign in? Username
Do you want to configure advanced settings? No, I am done.
✅ Successfully added auth resource reactamplified0123d75dfmod locally
✅ Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
UserXXXXXXX:~/environment/react-amplified-0001 (master) $
デフォルトのCognitoを使った認証で問題なければデフォルトのままで大丈夫です。
sign inのキー等、デフォルトから変更可能なようです。今回はデフォルトのままUsernameにしています。
続いて、amplify pushコマンドの実行です。
UserXXXXXXX:~/environment/react-amplified-0001 (master) $ amplify push
⠸ Fetching updates to backend environment: dev from the cloud.
⚠️ WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules
⠴ Fetching updates to backend environment: dev from the cloud.✅ GraphQL schema compiled successfully.
Edit your schema at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema
✔ Successfully pulled backend environment dev from the cloud.
Current Environment: dev
┌──────────┬────────────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name │ Operation │ Provider plugin │
├──────────┼────────────────────────────┼───────────┼───────────────────┤
│ Auth │ reactamplified0123d75dfmod │ Create │ awscloudformation │
├──────────┼────────────────────────────┼───────────┼───────────────────┤
│ Api │ reactamplified0001 │ No Change │ awscloudformation │
└──────────┴────────────────────────────┴───────────┴───────────────────┘
? Are you sure you want to continue? Yes
⚠️ Amplify CLI now supports verifying a Cognito user email address that has been changed and will automatically update your auth configuration. Read more: https://docs.amplify.aws/lib/auth/manageusers/q/platform/js/#updating-and-verifying-a-cognito-user-email-address
Deployment completed.
Deployed root stack reactamplified0001 [ ======================================== ] 3/3
amplify-reactamplified0001-de… AWS::CloudFormation::Stack UPDATE_COMPLETE Sat Dec 17 2022 02:35:33…
apireactamplified0001 AWS::CloudFormation::Stack UPDATE_COMPLETE Sat Dec 17 2022 02:32:44…
authreactamplified0001235mod0a AWS::CloudFormation::Stack CREATE_COMPLETE Sat Dec 17 2022 02:35:01…
Deployed auth reactamplified0001235dfmod [ ======================================== ] 10/10
UserPool AWS::Cognito::UserPool CREATE_COMPLETE Sat Dec 17 2022 02:32:31…
UserPoolClient AWS::Cognito::UserPoolClient CREATE_COMPLETE Sat Dec 17 2022 02:32:35…
UserPoolClientWeb AWS::Cognito::UserPoolClient CREATE_COMPLETE Sat Dec 17 2022 02:32:36…
UserPoolClientRole AWS::IAM::Role CREATE_COMPLETE Sat Dec 17 2022 02:33:13…
UserPoolClientLambda AWS::Lambda::Function CREATE_COMPLETE Sat Dec 17 2022 02:33:24…
UserPoolClientLambdaPolicy AWS::IAM::Policy CREATE_COMPLETE Sat Dec 17 2022 02:34:02…
UserPoolClientLogPolicy AWS::IAM::Policy CREATE_COMPLETE Sat Dec 17 2022 02:34:39…
UserPoolClientInputs Custom::LambdaCallout CREATE_COMPLETE Sat Dec 17 2022 02:34:46…
IdentityPool AWS::Cognito::IdentityPool CREATE_COMPLETE Sat Dec 17 2022 02:34:52…
IdentityPoolRoleMap AWS::Cognito::IdentityPoolRol… CREATE_IN_PROGRESS Sat Dec 17 2022 02:34:55…
GraphQL transformer version: 2
UserXXXXXXX:~/environment/react-amplified-0001 (master) $
こちらもDBの時と同様、認証に必要なAWSサービスがCloudFormationによって作成されていることがわかると思います。
最後に認証処理をsrc/App.jsに取り込んで手順完了です。
という流れなのですが、認証処理にAmplifyで用意されている認証画面等のUIライブラリを使用するのでUIライブラリの追加コマンドを事前に実行します。
UserXXXXXXX:~/environment/react-amplified-0001 (master) $ npm install @aws-amplify/ui-react
added 156 packages, and audited 2747 packages in 43s
257 packages are looking for funding
run `npm fund` for details
6 high severity vulnerabilities
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
UserXXXXXXX:~/environment/react-amplified-0001 (master) $
コマンド実行が無事に成功したら、改めて最後に認証処理をsrc/App.jsに取り込んで手順完了です。
/* src/App.js */
import React, { useEffect, useState } from 'react'
import { Amplify, API, graphqlOperation } from 'aws-amplify'
import { createTodo } from './graphql/mutations'
import { listTodos } from './graphql/queries'
import { withAuthenticator, Button, Heading } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
import awsExports from "./aws-exports";
Amplify.configure(awsExports);
const initialState = { name: '', description: '' }
const App = ({ signOut, user }) => {
const [formState, setFormState] = useState(initialState)
const [todos, setTodos] = useState([])
useEffect(() => {
fetchTodos()
}, [])
function setInput(key, value) {
setFormState({ ...formState, [key]: value })
}
async function fetchTodos() {
try {
const todoData = await API.graphql(graphqlOperation(listTodos))
const todos = todoData.data.listTodos.items
setTodos(todos)
} catch (err) { console.log('error fetching todos') }
}
async function addTodo() {
try {
if (!formState.name || !formState.description) return
const todo = { ...formState }
setTodos([...todos, todo])
setFormState(initialState)
await API.graphql(graphqlOperation(createTodo, {input: todo}))
} catch (err) {
console.log('error creating todo:', err)
}
}
return (
<div style={styles.container}>
<Heading level={1}>Hello {user.username}</Heading>
<Button onClick={signOut} style={styles.button}>Sign out</Button>
<h2>Amplify Todos</h2>
<input
onChange={event => setInput('name', event.target.value)}
style={styles.input}
value={formState.name}
placeholder="Name"
/>
<input
onChange={event => setInput('description', event.target.value)}
style={styles.input}
value={formState.description}
placeholder="Description"
/>
<button style={styles.button} onClick={addTodo}>Create Todo</button>
{
todos.map((todo, index) => (
<div key={todo.id ? todo.id : index} style={styles.todo}>
<p style={styles.todoName}>{todo.name}</p>
<p style={styles.todoDescription}>{todo.description}</p>
</div>
))
}
</div>
)
}
const styles = {
container: { width: 400, margin: '0 auto', display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: 20 },
todo: { marginBottom: 15 },
input: { border: 'none', backgroundColor: '#ddd', marginBottom: 10, padding: 8, fontSize: 18 },
todoName: { fontSize: 20, fontWeight: 'bold' },
todoDescription: { marginBottom: 0 },
button: { backgroundColor: 'black', color: 'white', outline: 'none', fontSize: 18, padding: '12px 0px' }
}
export default withAuthenticator(App);
Deploy and host app
では、いよいよ最後の手順です!
ホスティング環境にデプロイして動作確認してみましょう!!
公式ページは以下のページ。
ホスティング環境の追加は、amplify add hostingコマンドと、amplify publishコマンドで行います。(amplify pushコマンドではないので注意してください)
では、amplify add hostingコマンドを実行します。
UserXXXXXXX:~/environment/react-amplified-0001 (master) $ amplify add hosting
✔ Select the plugin module to execute · Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
? Choose a type Manual deployment
You can now publish your app using the following command:
Command: amplify publish
UserXXXXXXX:~/environment/react-amplified-0001 (master) $
Manual deploymentも出来るようですが、チュートリアルはデフォルトのままで大丈夫です。
無事にコマンド実行が成功すると思います。
では、いよいよ最後のコマンド、amplify publishコマンドの実行です。
UserXXXXXXX:~/environment/react-amplified-0001 (master) $ amplify publish
⠼ Fetching updates to backend environment: dev from the cloud.
⚠️ WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules
⠇ Fetching updates to backend environment: dev from the cloud.✅ GraphQL schema compiled successfully.
Edit your schema at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema.graphql or place .graphql files in a directory at /home/ec2-user/environment/react-amplified-0001/amplify/backend/api/reactamplified0001/schema
✔ Successfully pulled backend environment dev from the cloud.
Current Environment: dev
┌──────────┬────────────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name │ Operation │ Provider plugin │
├──────────┼────────────────────────────┼───────────┼───────────────────┤
│ Hosting │ amplifyhosting │ Create │ awscloudformation │
├──────────┼────────────────────────────┼───────────┼───────────────────┤
│ Api │ reactamplified0001 │ No Change │ awscloudformation │
├──────────┼────────────────────────────┼───────────┼───────────────────┤
│ Auth │ reactamplified0001235dfmod │ No Change │ awscloudformation │
└──────────┴────────────────────────────┴───────────┴───────────────────┘
? Are you sure you want to continue? Yes
Deployment completed.
Deployed root stack reactamplified0001 [ ======================================== ] 4/4
amplify-reactamplified0001-de… AWS::CloudFormation::Stack UPDATE_COMPLETE Sat Dec 17 2022 02:42:03…
hostingamplifyhosting AWS::CloudFormation::Stack CREATE_COMPLETE Sat Dec 17 2022 02:41:37…
apireactamplified0001 AWS::CloudFormation::Stack UPDATE_COMPLETE Sat Dec 17 2022 02:41:48…
authreactamplified0001235dfmod AWS::CloudFormation::Stack UPDATE_COMPLETE Sat Dec 17 2022 02:41:27…
Deployed hosting amplifyhosting [ ======================================== ] 1/1
AmplifyBranch AWS::Amplify::Branch CREATE_COMPLETE Sat Dec 17 2022 02:41:33…
GraphQL transformer version: 2
Publish started for amplifyhosting
> react-amplified-0001@0.1.0 build
> react-scripts build
Creating an optimized production build...
Compiled successfully.
File sizes after gzip:
269.4 kB build/static/js/main.76febmod.js
33.2 kB build/static/css/main.3d1modf8.css
1.79 kB build/static/js/787.0modb02d.chunk.js
The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.
The build folder is ready to be deployed.
You may serve it with a static server:
npm install -g serve
serve -s build
Find out more about deployment here:
https://cra.link/deployment
✔ Zipping artifacts completed.
✔ Deployment complete!
https://dev.XXXXXXXXXXXXXX.amplifyapp.com
UserXXXXXXX:~/environment/react-amplified-0001 (master) $
Are you sure you want to continue? で確認が求められ、問題なければそのまま継続するとデプロイが自動的に行われます。
最後に表示される以下がReactTodoアプリのアクセスURLになります。
https://dev.XXXXXXXXXXXXXX.amplifyapp.com
実際にアクセスすると以下の画面が表示されると思います。
Create Accountからユーザ登録してTodoアプリを触ってみましょう。
ユーザ登録には認証を追加した時のデフォルト設定でメールアドレスの認証設定が入っているので有効なメールアドレスが必要になります(ここで入力するメールアドレスに認証キーが送信されるのでその認証キーを次の画面に入力することでユーザ登録が完了になります)
これら全てAmplifyで用意されている自動処理になります。凄いですね。。。
以上です!!!
まとめ
以上でチュートリアルは終了です。
それなりに量があったのでなかなかの作業でしたがAmplifyの概念や基本操作が理解できる良いチュートリアルだったかなと思っています。
このチュートリアルを活かして自分なりのカスタマイズを徐々に増やしていこうと思います。
参考URL
- AmplifyCLI
- AmplifyJS
npm install aws-amplify
資格取得に向けてAWSサービスを実際に利用してみるシリーズの投稿一覧
とりあえず30分でAWS利用料金の高額請求に備える~予算アラート設定・MFA・料金確認~
AWS ECSでDocker環境を試してみる
Amazon Cognitoを使ってシンプルなログイン画面を作ってみる
AWS NATゲートウェイを使ってプライベートサブネットからインターネットにアクセスする
API GatewayをPrivateで作成してみる
AWSのAI(Rekognition/Polly/Transcribe/Comprehend/Translate/Textract)サービスを試してみる
AWS Lambda 同時実行数、エイリアス、環境変数とか実際の現場で使える機能を勉強してみる
AWS Lambda SAMとは?~AWS SAMを使ってPythonのLambdaプログラムを簡単に作成する~
AWS SAMを使って最もシンプルにLambda × APIGatewayのWebAPIを構築する
AWS SAMを使って最もシンプルにLambda × S3 のS3イベント駆動プログラムを構築する
Cloud9でAWS Amplifyの公式チュートリアルGetting startedをやってみる(本記事)