React + Amplify + AppSync + DynamoDB でサーバレスなWebアプリを作成する公式チュートリアルをやってみた

Amplifyを使って React + AppSync + DynamoDB でサーバレスなWebアプリを作成するチュートリアルをやってみました!
2020.03.27

大阪オフィスのYui(@MayForBlue)です。

最近プライベートでAWS Amplify(以下Amplify)を触っていて、良さげなチュートリアルを見つけたのでやってみました。
Amplifyを使って React + AppSync + DynamoDB でWebアプリを作成するものです。
デプロイについてはチュートリアルで紹介されているS3でのホスティングではなくAmplify Consoleを使ってCI/CDできるようにするなど少し工夫してやってみました。

Amplify JavaScript - Getting Started

このチュートリアルでは他にAngular、Vue、Ionic、React Nativeなどのフレームワークも選択できます。

そもそもAmplifyって何?という方には公式のウェビナーがおすすめです。
AWS Black Belt Online Seminar AWS Amplify - SlideShare
【AWS Black Belt Online Seminar】AWS Amplify

使用するAWSサービスの概要

  • Amplify:バックエンド構築プラットフォームのマネージドサービス
  • AppSync:GraphQLのマネージドサービス
  • DynamoDB:KeyValue型のNoSQLマネージドサービス

前提条件

  • Node.js バージョン8.x以降がインストールされていること
  • npm バージョン5.x以降がインストールされていること
  • Amplify CLI がインストールされていること

Amplify CLI のインストールとセットアップについてはこちらのブログをご参照ください。
Amplify CLI をインストールしてユーザーを設定する手順

手順

Reactアプリケーションを作成する

ローカルでReactアプリケーションを作成します。

$ npx create-react-app myapp

アプリケーションディレクトリに移動してAmplifyをインストールします。

$ cd myapp
$ npm install @aws-amplify/api @aws-amplify/pubsub

プロジェクトを実行してReactのウェルカムページが表示されることを確認します。

$ npm start


確認できたらCtrl+Cでプロジェクトを中断します。

バックエンドの初期設定をする

以下のコマンドを実行して、Amplifyのプロジェクト初期設定をします。

$ amplify init 

プロジェクト名を入力します。今回はデフォルトのまま、アプリケーション名と同じmyappにしました。

? Enter a name for the project myapp

環境変数を設定します。今回はdevとしました。

? Enter a name for the environment dev

使用するコードエディタを選択します。

? Choose your default editor:

アプリケーションのタイプを選択します。(android/ios/javascript)
今回はjavascriptを選択しました。

? Choose the type of app that you're building

使用するフレームワークを選択します。今回はreactを選択しました。

? What javascript framework are you using

以下は全てデフォルトのまま設定しました。

? 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

最後にプロファイルを使用するか選択します。
今回は使用するのでYを入力しました。使用しない場合はnを入力して、実行するIAMユーザーのアクセスキーとシークレットアクセスキーを入力します。

? Do you want to use an AWS profile?

使用するプロファイルを選択します。

? Please choose the profile you want to use

以下のような文章が表示されていたら設定完了です。

✔ Successfully created initial AWS cloud resources for deployments.
✔ Initialized provider successfully.
Initialized your environment successfully.

アプリケーションに設定が適用されていることを確認します。

$ amplify status
Current Environment: dev
| Category | Resource name | Operation | Provider plugin |
| -------- | ------------- | --------- | --------------- |

このあとバックエンドのリソースを追加していくと、テーブルにも反映されていきます。

マネジメントコンソールでもAmplifyのダッシュボードからアプリケーションが作成されていることが確認できます。

AppSync、DynamoDB をセットアップする

以下のコマンドでGraphQL、DynamoDBのセットアップをしていきます。

$ amplify add api 

GraphQLかREST APIのどちらを使用するか選択します。今回はGraphQLを選択します。

? Please select from one of the below mentioned services:GraphQL

API名を設定します。今回はデフォルトのままmyappとしました。

? Provide API name:myapp

APIの認証方法を選択します。今回はAPI Keyを選択しました。

? Choose the default authorization type for the API

必要に応じてAPIキーの説明を記述します、今回は空白のまま進めました。

? Enter a description for the API key:

APIキーの有効期限を設定します。今回はデフォルトのまま7日としました。

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

GraphQLの詳細設定を行うかどうかを選択します。今回はNoを選択しました。

? Do you want to configure advanced settings for the GraphQL API

GraphQLのスキーマファイルが既にあるかどうかを選択します。Noを選択しました。

? Do you have an annotated GraphQL schema?

ガイド付きでスキーマを作成するかどうかを選択します。Yesを選択しました。

? Do you want a guided schema creation?

どのようなプロジェクトかを選択します。
ID、タイトル、内容などのTodoリストのようなシンプルなものか、投稿とコメントのような1対多のブログのようなものかを選択します。
今回はTodoリストモデルのSingle object with fieldsを選択しました。

? What best describes your project: (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”)

スキーマを今すぐ編集するかどうかを選択します。
今回はデフォルトから変更しないのでnを入力しました。

? Do you want to edit the schema now? (Y/n)

以下のコマンドで、設定したリソースを作成します。

$ amplify push

この設定で作成していいかどうか聞かれるので、Yを入力します。

Current Environment: dev
| Category | Resource name | Operation | Provider plugin   |
| -------- | ------------- | --------- | ----------------- |
| Api      | myapp         | Create    | awscloudformation |
? Are you sure you want to continue? (Y/n)

以下の文章が表示されたら、正常にコンパイルが完了しています。

GraphQL schema compiled successfully.

続いてGraphQLのコードを作成するかどうか選択します。Yを選択しました。

? Do you want to generate code for your newly created GraphQL API

言語を選択します。

? Choose the code generation language target

クエリ、Mutations、Subscriptionsのファイル名パターンを入力します。今回はデフォルトのままとしました。

? Enter the file name pattern of graphql queries, mutations and subscriptions 

GraphQLの全ての操作に対してコードを生成するか選択します。今回はYを入力しました。

? Do you want to generate/update all possible GraphQL operations - queries, muta
tions and subscription

ネストする最大の深さを選択します。今回はデフォルトのまま2としました。

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

作成が完了すると、GraphQLのエンドポイントとAPI Keyが表示されます。

GraphQL endpoint: https://xxxxxxxxxxxxxxxxxx.appsync-api.ap-northeast-1.amazonaws.com/graphql
GraphQL API KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

マネジメントコンソールでも AppSync、DynamoDB のリソースが作成されていることが確認できます。

Reactアプリケーションを編集する

src/App.jsを以下のように編集します。
「Add Todo」のボタンをクリックするとcreateNewTodoの関数が実行され、GraphQLを経由してDynamoDBにデータが登録されるようになっています。

import React, { useEffect, useReducer } from 'react';

import API, { graphqlOperation } from '@aws-amplify/api';
import PubSub from '@aws-amplify/pubsub';

import { createTodo } from './graphql/mutations';
import { listTodos } from './graphql/queries';
import { onCreateTodo } from './graphql/subscriptions';

import awsconfig from './aws-exports';
import './App.css';

API.configure(awsconfig);
PubSub.configure(awsconfig);

// Action Types
const QUERY = 'QUERY';
const SUBSCRIPTION = 'SUBSCRIPTION';

const initialState = {
  todos: [],
};

const reducer = (state, action) => {
  switch (action.type) {
    case QUERY:
      return {...state, todos: action.todos};
    case SUBSCRIPTION:
      return {...state, todos:[...state.todos, action.todo]}
    default:
      return state;
  }
};

async function createNewTodo() {
  const todo = { name: "Use AWS AppSync", description: "RealTime and Offline" };
  await API.graphql(graphqlOperation(createTodo, { input: todo }));
}

function App() {
  const [state, dispatch] = useReducer(reducer, initialState);

  useEffect(() => {
    async function getData() {
      const todoData = await API.graphql(graphqlOperation(listTodos));
      dispatch({ type: QUERY, todos: todoData.data.listTodos.items });
    }
    getData();

    const subscription = API.graphql(graphqlOperation(onCreateTodo)).subscribe({
      next: (eventData) => {
        const todo = eventData.value.data.onCreateTodo;
        dispatch({ type: SUBSCRIPTION, todo });
      }
    });

    return () => subscription.unsubscribe();
  }, []);

  return (
    <div className="App">
      <button onClick={createNewTodo}>Add Todo</button>
      <div>
        {state.todos.length > 0 ? 
          state.todos.map((todo) => <p key={todo.id}>{todo.name} : {todo.description}</p>) :
          <p>Add some todos!</p> 
        }
      </div>
    </div>
  );
}

export default App;

アプリケーションをデプロイする

ここでチュートリアルではS3にホスティングしているのですが、今回はAmplify Console のCI/CDの機能を使いたかったのでGitHub経由でAmplify Consoleにデプロイしました。
チュートリアルの方法を用いる場合は以下のコマンドを実行してください。
S3での静的Webホスティングを有効化する

$ amplify add hosting

アプリケーションを公開する

$ amplify publish

Amplify Console でアプリケーションをデプロイする

GitHub経由でAmplify Consoleにデプロイします。
ソースコードをGitHubにpushします。
まずGitHubリポジトリを作成します。 Repositoriesのタブの「New」をクリックします。

リポジトリ名を入力して「Create repository」をクリックします。

リポジトリができたらアプリケーションのルートフォルダでソースコードをpushします。

$ git init
$ git add .
$ git commit -m "first commit"
$ git remote add origin git@github.com:【GitHubユーザー名】/【リポジトリ名】.git
$ git push origin master

マネジメントコンソールでAmplifyのダッシュボードに移動します。
対象のアプリケーションを選択します。

Frontend Enviromentsのタブで、リポジトリサービスに「GitHub」を選択して「次へ」をクリックします。

ビルド設定の構成でバックエンド環境を設定します。
「Deploy updates to backend resources with your frontend on every code commit」にチェックが入っているとCI/CDを行うことができます。
「Select a backend environment」で今回作成したdevの環境を選択します。
「Select an existing service role or create a new one so Amplify Console may access your resources.」でAmplifyコンソールがリソースにアクセスするためのロールを選択します。
使用するロールが存在しない場合は「Create new role」をクリックしてIAMロールを作成します。
設定ができたら「ビルドの設定」はデフォルトのままで画面下部の「次へ」をクリックします。
次のページで設定を確認して「保存してデプロイ」をクリックします。

GitHubのアカウントを認証して、リポジトリブランチの追加で対象のリポジトリ、masterブランチを選択して「次へ」をクリックします。

アプリケーションのプロビジョン〜検証が全て完了したら、サムネイルの下のURLをクリックしてアプリケーションがデプロイされていることを確認します。

「Add Todo」をクリックするとデータが登録されます。

DynamoDBのコンソールでもデータが追加されていることが確認できました。

アプリケーションの削除

作成したAmplifyアプリケーション、リソースを削除する場合は以下のコマンドを使用します。

$ amplify delete

以下の文章が表示されていたら正常に削除完了です。

✔ Project deleted in the cloud
Project deleted locally.

最後に

Amplifyを使ってReact + AppSync + DynamoDB でWebアプリを作成するチュートリアルをご紹介しました。
実際にアプリケーション作成からリソースの操作、ホスティングまで学べるのでとても勉強になりました。
気になった方は是非やってみてください!

また、以下のブログではAmplify Consoleのチュートリアルを紹介しています。
こちらも興味がある方は読んでみてください。
AmplifyでReactアプリのデプロイ、CI/CDをする公式チュートリアルをやってみた

以上、大阪オフィスのYui(@MayForBlue)でしたっ(`・ω・´)