AWS Amplifyの公式Reactチュートリアルをやってみる

本記事はAWS Amplifyの公式チュートリアル(React版)の手順を解説したものです。

Amplify Framework Documentation

チュートリアルで完成するアプリは認証機能付きのToDoアプリで、デプロイして公開するところまで学べます。なおチュートリアルにはサインアウト機能はないのですが、それだとアプリの動作確認がやり辛いので本記事では「SIGN OUT」ボタンを追加しています。

完成アプリのシステム構成
完成アプリのシステム構成

 

Reactアプリ_承認画面

Reactアプリ_メイン画面

前提環境

以下の環境が必要となります。

Node.js v10.x or later
npm v5.x or later
git v2.14.1 or later

筆者のローカル環境は下記のとおりです。

% node -v
v14.3.0

% npm -v
6.14.5

% git –version
git version 2.14.2

AWSのアカウント作成

AWSアカウントの作成方法はAWSが別途ガイドを出しているのでそちらを参照しながら作成してください。

Amplify CLIのインストールと初期セットアップ

次のコマンドでAmplify CLIをインストールします。

% npm install -g @aws-amplify/cli

 

次のコマンドでAmplify CLIのセットアップを開始します。

% amplify configure

 

ブラウザが立ち上がりAmazonアカウントにログインするように求められますのでログインしたらターミナルに戻ります。

コマンドラインでEnterキーを押すと次の設定に進み、以下のようにリージョン選択画面になります。本記事では「ap-northeast-1」(東京リージョン)を選択しました。

Specify the AWS Region
? region:
   eu-west-1
   eu-west-2
   eu-central-1
❯ ap-northeast-1
   ap-northeast-2
   ap-southeast-1
   ap-southeast-2

 

続いて作成するIAMユーザー名の入力を求められますので適当な名前を入力してEnterキーを押すとブラウザが立ち上がります。ブラウザ上では特に変更することなく右下のボタンをクリックし処理を進めてIAMユーザーを作成してしまって問題ありません。IAMユーザーの作成が完了するとアクセスIDとアクセスキーを得られます。

Specify the username of the new IAM user:
? user name: (amplify-tRnq7)

IAMユーザー作成1

IAMユーザー作成2

IAMユーザー作成3

IAMユーザー作成4

IAMユーザー作成5

 

ターミナルに戻ってEnterキーを押して処理を進めます。上記の手順で取得したアクセスIDとアクセスキーを入力してプロファイル名はデフォルトのままとしてそのままEnterキーを押します。これでAmplify CLIの初期セットアップ完了です。

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

Reactアプリの作成とAmplifyの初期セットアップ

Reactアプリの作成

次のコマンドでReactアプリを作成してからアプリのルートディレクトリに移動します。青字は本記事でのReactアプリ名です。

% npx create-react-app react-amplify-demo
% cd react-amplify-demo

 

Amplifyの初期セットアップ

Reactアプリのルートディレクトリで次のコマンドを実行してAmplifyのセットアップを開始します。

% amplify init

 

対話形式でセットアップが進みます。以下青字部分は本記事での入力内容です。デフォルトで入力されているものでOKだったので、そのままEnterキーを押して一気に進めます。

? Enter a name for the project reactamplifydemo
? Enter a name for the environment dev
? Choose your default editor: Visual Studio Code
? Choose the type of app that you’re building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path: src
? Distribution Directory Path: build
? Build Command: npm run-script build
? Start Command: npm run-script start

 

最後にAWSプロファイルを使うかを尋ねられます。これはAWS CLIの接続に使うアクセス情報を指定できる仕組みです。本記事ではYesを選択してから利用するプロファイルはdefalutを選択しました(本記事においてはdefaultしか選択肢が出てこないです)。なお「Y/n」と表示されている場合は、大文字の「Y」がデフォルト値を意味します。

? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use default

 

以上でAmplifyの初期セットアップ完了です。

AWSのAmplifyコンソールを開くと初期セットアップで指定した「reactamplifydemo」が作成されているのが下図のとおり確認できます。さらに「View in CloudFormation」で詳細を確認してみます。

Amplify_1

 

CloudFormationのデザイナーでリソースを確認するとS3バケットと2つのIAMロールが作成されていたことがわかります。

CloudFormation

 

ローカル環境のReactアプリも更新されていて、以下Amplify関連のファイル(赤字)が追加されています。そして.gitignore(青字)にはAmplify関連が追加されています。

% tree -I node_modules -L 2 -a
.
(省略)
├── .gitignore
├── .vscode
│   └── settings.json
├── README.md
├── amplify
│   ├── #current-cloud-backend
│   ├── .DS_Store
│   ├── .config
│   ├── backend
│   ├── cli.json
│   └── team-provider-info.json
(省略)
├── src
│   ├── App.css
│   ├── App.js
│   ├── App.test.js
│   ├── aws-exports.js
│   ├── index.css
│   ├── index.js
│   ├── logo.svg
│   ├── reportWebVitals.js
│   └── setupTests.js
└── yarn.lock

Amplifyライブラリのインストールとセットアップ

Reactアプリのルートディレクトリで次のコマンドを実行してReactアプリで利用するAmplifyライブラリをインストールします。

% npm install aws-amplify @aws-amplify/ui-react

 

Reactアプリのsrc/index.jsに下図コードを追記してAmplifyのセットアップをします。

import Amplify from “aws-amplify”;
import awsExports from “./aws-exports”;
Amplify.configure(awsExports);

GraphQL APIとデータベースの構築

次のコマンドをReactアプリのルートディレクトリで実行して対話形式でAPIのセットアップを開始します。

% amplify add api

 

AmplifyではAPIとしてGraphQLかRESTを選択可能ですが、本記事ではチュートリアルどおりGraphQLを選択します。

? Please select from one of the below mentioned services: (Use arrow keys)
❯ GraphQL
  REST

 

API名の入力を求められます。デフォルトで設定されている名前のとおりとして、そのままEnterキーを押します。

? Provide API name: (reactamplifydemo)

 

チュートリアルと同様に「API key」を選択します。

? Choose the default authorization type for the API (Use arrow keys)
❯ API key
  Amazon Cognito User Pool
  IAM
  OpenID Connect

 

API keyの記述は「demo」としてEnterキーを押します。

? Enter a description for the API key: demo

 

API keyの期限を尋ねられます。デフォルトの7日のままとして、そのままEnterキーを押します。

? After how many days from now the API key should expire (1-365): (7)

 

GraphQLのアドバンス設定をするかを問われますが、チュートリアルと同様「No, I am done.」を選択します。

? Do you want to configure advanced settings for the GraphQL API (Use arrow keys)
❯ No, I am done.
  Yes, I want to make some additional changes.

 

GraphQLスキーマがあるかを問われますが自動作成してもらいますのでEnterキーをそのまま押します。

? Do you have an annotated GraphQL schema? (y/N)

 

自動生成されるGraphQLスキーマのテンプレートを選択します。1対多関係のモデルタイプ選択できるようですが、チュートリアルではシンプルな「Single object with fields」を選択します。

? Choose a schema template: (Use arrow keys)
❯ Single object with fields (e.g., “Todo” with ID, name, description)
  One-to-many relationship (e.g., “Blogs” with “Posts” and “Comments”)

 

GraphQLのスキーマを編集するかを尋ねられます。後続では自動生成されたスキーマをそのまま使うので「N」入力でもよいですが、チュートリアルに従い「y」と入力してEnterキーを押します。

The following types do not have ‘@auth’ enabled. Consider using @auth with @model
– Todo
Learn more about @auth here: https://docs.amplify.aws/cli/graphql-transformer/directives#auth

GraphQL schema compiled successfully.

Edit your schema at /Users/user/react-amplify-demo/amplify/backend/api/reactamplifydemo/schema.graphql or place .graphql files in a directory at /Users/user/react-amplify-demo/amplify/backend/api/reactamplifydemo/schema
? Do you want to edit the schema now? (y/N) y

 

以下のメッセージが表示され以前の手順で選択したデフォルトエディタでGraphQLスキーマ定義ファイル「amplify/backend/api/myapi/schema.graphql」が開きます。

Please edit the file in your editor: /Users/user/react-amplify-demo/amplify/backend/api/reactamplifydemo/schema.graphql
Successfully added resource reactamplifydemo 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

 

自動生成されたGraphQLスキーマ定義ファイル「amplify/backend/api/myapi/schema.graphql」は下記のとおりです。「@model」が付与されたオブジェクトモデルは、自動的にDynamoDBへのテーブル登録およびGraphQLのCRUD用Query/Mutation/Subscriptionが構成されます。

type Todo @model {
  id: ID!
  name: String!
  description: String
}

 

APIのデプロイ

次のコマンドをReactアプリのルートディレクトリで実行してAPIのデプロイを開始します。

% amplify push

 

次のメッセージが表示されAPIの構築が行われることが確認でき、「Y」を入力しEnterキーを押して先に進めます。

✔ Successfully pulled backend environment dev from the cloud.

Current Environment: dev

| Category |  Resource name   | Operation | Provider plugin   |
| -------- | ---------------- | --------- | ----------------- |
|   Api    | reactamplifydemo |  Create   | awscloudformation |
? Are you sure you want to continue? (Y/n) Y

 

次のメッセージが出てGraphQL APIの操作コードを自動生成するかを問われます。「Y」を入力してEnterキーを押します。

The following types do not have ‘@auth’ enabled. Consider using @auth with @model
– Todo
Learn more about @auth here: https://docs.amplify.aws/cli/graphql-transformer/directives#auth

GraphQL schema compiled successfully.

Edit your schema at /Users/user/react-amplify-demo/amplify/backend/api/reactamplifydemo/schema.graphql or place .graphql files in a directory at /Users/user/data/11_react/react-amplify-demo/amplify/backend/api/reactamplifydemo/schema
? Do you want to generate code for your newly created GraphQL API (Y/n) Y

 

GraphQL API操作言語を選択します。チュートリアルでは「javascript」を選択します。

? Choose the code generation language target (Use arrow keys)
❯ javascript
  typescript
  flow

 

GraphQL API 操作コードのパスを指定します。デフォルトのまま先に進めるため、そのままEnterキーを押します。

? Enter the file name pattern of graphql queries, mutations and subscriptions (src/graphql/**/*.js)

 

GraphQL APIの全ての操作コードを生成するかを尋ねられます。「Y」を入力してEnterキーを押します。

? Do you want to generate/update all possible GraphQL operations – queries, mutations and subscriptions (Y/n) Y

 

GraphQLスキーマ定義ファイル「amplify/backend/api/myapi/schema.graphql」のスキーマネスト構造をどこまで深く読み込むかを問われます。チュートリアルではデフォルト値の2のままEnterキーを押します。

? Enter maximum statement depth [increase from default if your schema is deeply nested] (2)

 

数分するとデプロイが完了し、以下のメッセージが出力されます。
「src/graphql」ディレクトリにGraphQL APIの操作コードも出力され、バックエンドの構築およびGraphQLのエンドポイントとAPIキーも作成されたことがわかります。

(省略)

✔ Generated GraphQL operations successfully and saved at src/graphql
✔ All resources are updated in the cloud

GraphQL endpoint: https://xxx.amazonaws.com/graphql
GraphQL API KEY: xxx

 

Reactアプリ内では以下赤字部分(GraphQL API操作コード)が追加されました。

% tree -I node_modules -L 3
.
(省略)
├── src
│   ├── App.css
│   ├── App.js
│   ├── App.test.js
│   ├── aws-exports.js
│   ├── graphql
│   │   ├── mutations.js
│   │   ├── queries.js
│   │   ├── schema.json
│   │   └── subscriptions.js
│   ├── index.css
│   ├── index.js
│   ├── logo.svg
│   ├── reportWebVitals.js
│   └── setupTests.js
└── yarn.lock

 

AmplifyコンソールでAPIを確認するとGraphQL APIとData sources(= DynamoDB)が構築されたのが見てとれます。

Amplifyコンソール_API

 

Reactアプリの修正

src/App.jsを丸ごと次のコードに置き換えます。

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

 

以上でReactアプリへのToDoアプリの組み込みとバックエンドとの接続が完了しました。

「npm start」でReactアプリをローカル環境上で起動するとToDoアプリが動くようになっています。

Amplifyデモアプリ

認証機能の追加

このセクションではユーザー名とパスワードによる認証機能をReactアプリに追加します。

認証サービスのデプロイ

次のコマンドをReactアプリのルートディレクトリで実行して対話形式で処理を進めます。

% amplify add auth

 

Amazon Cognitoサービスを使って認証機能を構築する旨メッセージが出てCognitoのユーザープールとIDプールを自動で作成するかどうかを尋ねられます。本記事ではチュートリアルと同様「Default configuration」を選択します。これはユーザープールとIDプールを両方とも自動作成することになります。


ユーザープール: サインアップとサインインのユーザー情報を管理してくれるユーザーディレクトリ
IDプール: AWSの他のサービスにアクセスするための情報を管理してくれる
Using service: Cognito, provided by: awscloudformation

The current configured provider is Amazon Cognito.

Do you want to use the default authentication and security configuration? (Use arrow keys)
❯ Default configuration
  Default configuration with Social Provider (Federation)
  Manual configuration
  I want to learn more.

 

次にサインインの方法について問われますがチュートリアルどおり「Username」を選択します。

How do you want users to be able to sign in? (Use arrow keys)
❯ Username
  Email
  Phone Number
  Email or Phone Number
  I want to learn more.

 

アドバンス設定をすかを尋ねられますが、「No, I am done」を選択します。

Do you want to configure advanced settings? (Use arrow keys)
❯ No, I am done.
  Yes, I want to make some additional changes.

 

続いてAmplifyコマンドを使って認証サービスをデプロイします。Reactアプリのルートディレクトリで「amlify push」と打つとAuthについてデプロイすると確認でき、続けるかと問われるので「Yes」として続けます。数分するとデプロイが完了します。

% amplify push
✔ Successfully pulled backend environment dev from the cloud.

Current Environment: dev

| Category | Resource name | Operation | Provider plugin |
| ——– | ———————— | ——— | —————– |
| Auth | reactamplifydemoac4ea214 | Create | awscloudformation |
| Api | reactamplifydemo | No Change | awscloudformation |
? Are you sure you want to continue? Yes

 

Reactアプリに認証機能を追加

src/App.jsで以下赤字のとおりコードを追加します。チュートリアルにはサインアウト機能はないのですが、本記事では「AmplifySignOut」コンポーネントを利用してサインアウト機能を追加しています。

(省略)
import { withAuthenticator, AmplifySignOut } from ‘@aws-amplify/ui-react’
(省略)
<button style={styles.button} onClick={addTodo}>Create Todo</button>
<AmplifySignOut/>
(省略)
export default withAuthenticator(App)
認証画面

Reactアプリのデプロイ

最後にReactアプリを公開します。

次のコマンドでReactアプリのデプロイ処理を開始します。

% amplify add hosting

 

次にチュートリアルではホスティング作業をより自動化できるAmplify Consoleを選択します。「Hosting with Amplify Console」を選んで先に進めます。

? Select the plugin module to execute (Use arrow keys)
❯ Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
  Amazon CloudFront and S3

 

デプロイ方法を問われます。Continuous deployment(継続的デプロイ)を選択しGitと連携することも可能ですが、チュートリアルどおり「Manual deployment」を選択します。

? Choose a type (Use arrow keys)
Continuous deployment (Git-based deployments)
❯ Manual deployment
  Learn more

 

「amplify publish」コマンドでReactアプリを公開します。以下のメッセージが表示されHostingのみ対象に処理が進むことを確認し「Yes」を選択して処理を進めます。

% amplify publish
✔ Successfully pulled backend environment dev from the cloud.

Current Environment: dev

| Category |      Resource name       | Operation |  Provider plugin  |
| -------- | ------------------------ | --------- | ----------------- |
| Hosting | amplifyhosting | Create | awscloudformation |
| Api | reactamplifydemo | No Change | awscloudformation |
| Auth | reactamplifydemoac4ea214 | No Change | awscloudformation |
? Are you sure you want to continue? Yes

 

数分で以下のメッセージが表示され処理が完了します。メッセージの最後に公開URLが表示されます。

(省略)
✔ Deployment complete!
https://dev.d104gaau0651za.amplifyapp.com
アプリに修正を入れた場合は再び「amplify publish」コマンドを実行すればデプロイされます。
sponsor