この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。
今回、Amplifyを使用した簡単なWebサイトの構築 後編 です。前編は下記のリンクを参照してください
API を利用した GraphQL API の構築
※ Tutorial – Connect API and database to the app – React – 参照してください
AWS AppSync と Amazon DynamoDB を Amplify CLI で構築していきます
- AppSync
・GraphQL API の開発を容易にするマネージドサービス
・データソースとの接続に必要な作業を自動的に処理
・キャッシュやサブスクリプション、自動的なスケール処理などが特徴
- Dynamo DB
・サーバレスサービスでパフォーマンスやスケーラビリティの高さが特徴
・ACIDトランザクションや暗号化などミッションクリティカルなワークロードにも対応
API の追加
まずは API を追加します
API を追加するコマンドを実行します
amplify add api
作成する API を聞かれるので、今回は AppSync を使用するので GraphQL を選択
次に API 名や認証方式を聞かれるので、デフォルトで進めます
次にスキーマのテンプレートについて聞かれるので、Single object with fields で進めていきます
スキーマを今、編集しますか?と聞かれるので n を入力
Amplify と API コマンドが完了しました。この状態では cloud上に設定が反映されていないので、Amplify上のリソースを確認します
amplify status
Operation が Create (作成待ち) が確認できました。これらを反映させます
amplify push
リソースが作成されますと聞かれているので Y を入力
GraphQL API を作成されますも Y を入力
言語は javascript を選択
次はデフォルトで進め、全てのGraphqlを対象に生成更新をかけるので Y を選択
次もデフォルト2のままで進めます。少し時間がかかるのでお待ちください
↓
amplify push コマンドが完了しました
次に先ほど生成した API を利用するフロントエンドにソースコードを書き換えていきます
ソース 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
↓
上書き完了したら動作確認を行います。コマンドを実行
npm start
サーバーが起動したら先ほど同様 Preview → Preview Running Application で動作確認をします
↓
Todo アプリが動作していることが確認できました
↓
Name と Descliption を入力して Todo を作成することが確認できました
こちらのバックエンドでは先ほど構築した AppSync や Dynamo DB といったバックエンドが利用されています
ユーザーのログイン機能を追加
作成したアプリケーションにユーザーのログイン機能を実装していきます。Amplify CLI を利用して Amazon Cognito の認証機能を追加します
- Amazon Cognito
・ウェブおよびモバイルアプリの認証、承認、およびユーザー管理機能を提供
・ユーザープール
・アプリへのアクセスに利用できるトークンを提供
・ID プール
・AWS にアクセルできるクレデンシャルを提供
1. Amplify CLI で Auth の追加
※ Tutorial – Add authentication – React – 参照してください
認証機能を追加します。コマンドを実行
amplify add auth
認証に関する詳細な設定を行うことができますが、今回はデフォルトで進めていきます
サインインの方法を聞かれるので、今回はユーザーネームを使って認証を選択
詳細設定を行うかと聞かれるので、No を選択
これで認証の定義が追加されたのでコマンドを実行して確認します
amplify status
Category に Auth が追加されていて Operation が Create になっていることが確認できました
次に Auth をデプロイするため amplify push
を実行します
Y を選択します。少し時間がかかります
デプロイが完了しました
2. ログイン UI 作成
次にログイン UI を作成していきます。App.js を変更します
以下を追加し、withAuthenticator component をインポートしていきます
import { withAuthenticator, Button, Heading } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
↓
次に const App = () => {
をコメントアウトして
function App({ signOut, user }) {
を追加します
次に return に以下を追加します
<Heading level={1}>Hello {user.username}</Heading>
<Button onClick={signOut}>Sign out</Button>
末尾にある export default App
を export default withAuthenticator(App);
に修正
↓
変更後の 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 = () => {
function 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}>
<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>
}
<Heading level={1}>Hello {user.username}</Heading>
<Button onClick={signOut}>Sign out</Button>
</>
);
}
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);
npm start
で動作確認をしていきます
サーバーが起動したので Preview → Preview Running Application で動作確認をします
アカウントが存在しないので Create Account で確認します
ユーザーネーム、パスワード、Eメールアドレスを入力したら Create Account をクリック
登録したEメールアドレスに二要素認証コードが送られてくるので入力して Confirm をクリック
↓
二要素認証コードが通りログインできました。作成されたアカウントのユーザーネームが表示されています
アプリケーションのホスティング
作成した HTML などのファイルを AWS Amplify Console Static Web Site Hpsting の機能を使いデプロイしていきます
アプリケーションの静的ファイルにホスティング機能を追加
コマンドを実行します
amplify add hosting
プラグインモジュールを処理するサービスを選択。今回は Hosting with Amplify Console を選択します
次にデプロイのタイプを選択します。今回はマニュアルデプロイメントを選択
これでホスティング設定の追加が完了です。コマンドで確認します。
amplify status
新しく追加した Hosting が Create になっていることが確認できました
最後にアプリを公開します。 amplify publish
を実行します
amplify publish は クラウドリソースへの変更を行ったうえで Webアプリケーションを手元でビルドし、Amplify Console でホスティングされたアプリケーションを更新します
リソースの変更内容に問題ない事を確認して Y を入力
完了しました。URLをクリックして確認します
表示されたらユーザーネームとパスワードを入力してログインします
ログインでき作成したデーターが登録されていることが分かりました。試しに Todo を作成してみましょう
↓
作成できました。以上で今回の Amplify を使用した Webサイトの構築は終了です。
※ 作成したリソースは料金が発生するサービスもあるため削除してください
ルートディレクトリでコマンド amplify delete
リソースの削除ができます
最後に
今回は Amplify がどういったのもかを学ぶために実際に触りながら簡単な Web サイトの構築を実施しました。少し長い記事になりましたが、読んでいただきありがとうございました。