AWS Startup ブログ
【お手軽ハンズオンで AWS を学ぶ】AWS Amplify で Todo アプリを作ろう! AWS AppSync & Amazon DynamoDB によるリアルタイムメッセージング
AWS Amplify は、モバイルアプリやウェブアプリの実装を手助けしてくれるフレームワークです。AWS 上のバックエンドをプロビジョニングすることで、iOS や Android 、 Web 、React Native 上などにあるフロントエンドと簡単に統合させることが可能になります。開発スピードが最重要視されるスタートアップにおいて、AWS Amplify が役に立つ場面は多いでしょう。
この記事では、2019年8月8日に開催された「AWS Amplify & Chalice ハンズオン 〜怠惰なプログラマ向けお手軽アプリ開発手法〜」の内容をベースに、 AWS Amplify で AWS AppSync と Amazon DynamoDB を用いた Todo リストアプリを構築する手順を、ハンズオン形式で解説していきます。
同じ日に開催した、Chalice による Python アプリ開発誌上ハンズオン記事はこちらをご覧下さい。
環境構築
作業に入る前に、まずは以下の環境構築を行いましょう。
Node.js および npm のインストール
Node.js のバージョンは 8.x 以上、 npm のバージョンは 5.x 以上がインストールされていることを確認してください。
$ node -v
v8.10.0
$ npm -v
6.10.1
AWS Amplify CLI@1.8.0 のインストール
バージョンによる挙動や表示の違いを除外するため、このハンズオンでは AWS Amplify CLI の 1.8.0 を前提として作業します。
$ npm install -g @aws-amplify/cli@1.8.0
$ amplify configure
amplify configure
コマンドを実行すると、ブラウザで AWS マネジメントコンソールが立ち上がるので、ログインしてください。
ログイン後はターミナルに戻り、 Enter キーを押しましょう。使用するリージョンや IAM ユーザー名を聞かれますが、デフォルト(us-east-1, amplify-******)のままで構いません。
その後、再度ブラウザで AWS マネジメントコンソールが立ち上がるので、画面の説明に沿って IAM ユーザーを作成していきましょう(※)。
ハンズオンの作業環境として AWS Cloud9 を利用している場合には注意が必要です。 AWS Cloud9 ではデフォルトの一時認証情報を利用できますが、その認証情報を使用すると、ハンズオンの後続の作業に支障が出てしまいます。本ハンズオンでは、永続的な Profile を作成して使用しましょう。
1.ユーザー作成
ユーザー名は何にしても構いません。この例では「amplify-xPAtd」としました。 AWS アクセスの種類は「プログラムによるアクセス」にチェックを入れ、「次のステップ: アクセス権限」ボタンを押します。
2.IAMポリシーのアタッチ
「Administrator Access」にチェックを入れ、にチェックを入れ、「次のステップ: タグ」ボタンを押します。
3.タグの追加
ここでは何も設定を行わず、「次のステップ: 確認」ボタンを押します。
4.作成内容の確認
設定した内容に誤りがないか確認し、「ユーザーの作成」ボタンを押します。
5.ユーザー作成完了
これで、IAM ユーザーの作成が完了します。この画面に表示されている情報を使用するため、ブラウザを閉じないように注意しましょう。
ターミナルに戻り、 Enter キーを押します。アクセスキー ID やシークレットアクセスキー ID を聞かれるので、ブラウザの IAM ユーザー作成完了画面に表示されているものをコピーしてください。Profile Name はデフォルト(default)のままでも構いませんが、後でわかりやすくするために、ここでは amplify-handson
とします。
Vue CLI のインストールと新規 Vue アプリのひな型作成
本ハンズオンでは、アプリのUI構築のために Vue.js を使用します。以下のコマンドを入力して、 Vue CLI をインストールし、新規 Vue アプリを myamplifyproject という名前で作成しましょう。
$ npm install -g @vue/cli
$ vue create myamplifyproject
$ cd myamplifyproject
myamplifyproject
ディレクトリの中で、 AWS Amplify のモジュールをインストールします。@aws-amplify/api
はアプリに API 機能を、 @aws-amplify/pubsub
はアプリにメッセージング機能を追加するモジュールです。
$ npm i @aws-amplify/api @aws-amplify/pubsub
$ npm run serve
インストール後、アプリを起動しましょう。成功すると、ターミナルの標準出力にアプリの URL が「App running at: – Local: http://localhost:8080/」のような形で表示されます。http://localhost:8080/ にアクセスして、「Welcome to Your Vue.js App」というメッセージが表示されたら成功です(※)。ここまでできれば、準備は完了です。次章からアプリ作成に移っていきましょう。
ハンズオンの作業環境として AWS Cloud9 を利用している場合は注意が必要です。 AWS Cloud9 のターミナルから npm run serve コマンドを実行し、ブラウザで IP アドレスを指定して Vue アプリにアクセスしても、うまく接続できないケースがあります。この原因は、外部ホストからの接続が許可されていないことにあります。以下の方法で対処しましょう。
1.プロジェクトのルートディレクトリ直下に vue.config.js ファイルを作成する。
2.作成した vue.config.js ファイル内に、以下のコードを記述して保存する。
module.exports = {
devServer: {
disableHostCheck: true
}
}
Step 1 : サーバーレスなバックエンドの作成
このハンズオンでは、 Amplify Framework を使って以下のステップで作業を実施していきます。
1. AWS Amplify CLI ツールチェーンを使って、サーバーレスなバックエンドを作成
2. アプリケーションから、 AWS Amplify を使ってバックエンドにアクセス
3. AWS AppSync と Amazon DynamoDB によるリアルタイムメッセージング
4. アプリケーションのリリース
本ステップでは、まず「AWS Amplify CLI ツールチェーンを使って、サーバーレスなバックエンドを作成」の作業を行いましょう。 myamplifyproject
ディレクトリのトップで、 amplify init
コマンドを実行します。
$ amplify init
このような入力項目が表示されます。 environment name
には test
と入力し、エディタは好きなものを選んでください。その他の選択肢はデフォルトで構いません(※)。
事前準備で amplify configure を正しく完了していない場合には、途中で「? Setup new user」と表示され、新しいユーザーをセットアップするか聞かれます。その場合、 Y と答えると、ブラウザで AWS マネジメントコンソールが立ち上がるので、マネジメントコンソールにログインしてください。その後は、事前準備の amplify configure 実行時の手順に従い、 Profile の作成を進めましょう。「? Setup new user」ではなく「? Do you want to use an AWS profile?」と聞かれている場合は、 Enter を押し、利用する Profile (amplify-handson など) を選択してください。
Profile の選択が済むと、 AWS CloudFormation によって、アプリケーションのバックエンドに必要な基礎的な AWS リソース(IAM Role や Amazon S3 バケットなど)が、自動的に作成されます。
AWS Amplify CLI が正しく設定されていることを確認するために、 amplify status コマンドを実行しましょう。何も値がない表が表示されれば正常です。
$ amplify status
| Category | Resource name | Operation | Provider plugin |
| -------- | ------------- | --------- | --------------- |
この後の手順で、 amplify add
コマンドによってアプリケーションに機能を追加し、 amplify push
コマンドを実行すると、作成されたバックエンドリソースがこの表に表示されるようになります。次のコマンドで、 GraphQL API と自動設定されるデータベースをアプリケーションに追加します。
$ amplify add api
いくつか入力項目が表示されますが、すべてデフォルト設定で構いません。このハンズオンでは AWS AppSync と Amazon DynamoDB を使って Todo リストを実現するため、 What best describes your project: に対し Single object with fields (e.g., “Todo” with ID, name, description) と入力します。
Do you want to edit the schema now? に Yes と答えたため、生成された GraphQL スキーマファイルのパスが「〜/myamplifyproject/schima.graphql」と表示されています。このファイルに記述されている内容は、以下のように非常にシンプルです(※)。
type Todo @model {
id: ID!
name: String!
description: String
}
※…@model アノテーションは、少ない記述で CRUD 処理を可能にする変換用のディレクティブです。興味のある方は GraphQL Transform を参照してください。
この状態で amplify status
コマンドを実行すると、先ほどの表に API 機能が追加されていることが分かります。
$ amplify status
Current Environment: test
| Category | Resource name | Operation | Provider plugin |
| -------- | ---------------- | --------- | ----------------- |
| Api | myamplifyproject | Create | awscloudformation |
この情報をバックエンドに反映するため、 amplify push
コマンドを実行してください。途中で表示される選択肢はデフォルトで構いません。生成するコードのターゲットとして表示される選択肢は、このハンズオンでは javascript
を使用します。コマンド実行後、 AWS CloudFormation による Update Stack が自動的に行われることを確認しましょう。
$ amplify push
Step 2 : アプリケーションから、 AWS Amplify を使ってバックエンドにアクセス
先ほど作成した素の Vue アプリは、まだ何の機能も持っていませんでした。 AWS Amplify が生成したバックエンドに接続するため、 Amplify.configure() メソッドを使うように main.js ファイルを編集します。
main.js
import Vue from 'vue'
import App from './App.vue'
import API from '@aws-amplify/api';
import PubSub from '@aws-amplify/pubsub';
import awsconfig from './aws-exports';
API.configure(awsconfig);
PubSub.configure(awsconfig);
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
データの新規登録
次に App.vue ファイルを開き、コードを以下のように編集します(元のコードは消して構いません)。ボタン押下時に、 API.graphql() メソッドを用いて GraphQL の mutation を発行し、新規データを登録するための処理です。
App.vue
<template>
<div id="app">
<button @click="createNewTodo">Add Todo</button>
</div>
</template>
<script>
import API, { graphqlOperation } from '@aws-amplify/api';
// eslint-disable-next-line
import { createTodo } from "./graphql/mutations";
/*
Supported log levels for browser debugging:
ERROR
WARN
INFO
DEBUG
VERBOSE
@see https://aws-amplify.github.io/docs/js/logger
*/
window.LOG_LEVEL = 'VERBOSE';
export default {
name: 'app',
methods :{
async createNewTodo(){
const todo = { name: "Todo Title" , description: "あれをやる" + Date()}
await API.graphql(graphqlOperation(createTodo, { input: todo }))
}
}
};
</script>
npm run serve
コマンドでローカルサーバーを立ち上げて http://127.0.0.1:8080 にアクセスすると、シンプルなボタンがひとつ表示されます。押下するとバックエンドの AWS AppSync を通じて、 Amazon DynamoDB にレコードが追加されます。
登録したデータの表示
登録されているデータをページロード時に一覧表示するため、 App.vue の Vue のライフサイクルメソッドである created()
に、データを取得・表示する処理を追加します。 AWS Amplify が生成した GraphQL スキーマである listTodos
をインポートして使いましょう。
App.vue(前との差分を意識しながら編集してみてください)
<template>
<div id="app">
<button @click="createNewTodo">Add Todo</button>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{todo.name}} - {{todo.description}}
</li>
</ul>
</div>
</template>
<script>
import API, { graphqlOperation } from '@aws-amplify/api';
// eslint-disable-next-line
import { createTodo } from "./graphql/mutations";
import { listTodos } from './graphql/queries'
window.LOG_LEVEL = 'VERBOSE';
export default {
name: 'app',
data(){
return {
todos: []
}
},
methods :{
async createNewTodo(){
const todo = { name: "Todo Title" , description: "あれをやる" + Date()}
await API.graphql(graphqlOperation(createTodo, { input: todo }))
},
async getData(){
const todoData = await API.graphql(graphqlOperation(listTodos))
this.todos.push(...this.todos, ...todoData.data.listTodos.items);
}
},
created(){
this.getData()
}
};
</script>
ブラウザを更新すると、投稿されていた Todo が一覧表示されます。
Step 3 : AWS AppSync と Amazon DynamoDB によるリアルタイムメッセージング
次は、新しい Todo データが投稿されたら、表示内容も自動的に更新するように変更してみましょう。 GraphQL スキーマの onCreateTodo subscription をインポートして、 API.graphql()
メソッドを使った処理を追加します。
App.vue
<template>
<div id="app">
<button @click="createNewTodo">Add Todo</button>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{todo.name}} - {{todo.description}}
</li>
</ul>
</div>
</template>
<script>
import API, { graphqlOperation } from '@aws-amplify/api';
// eslint-disable-next-line
import { createTodo } from "./graphql/mutations";
import { listTodos } from './graphql/queries';
import { onCreateTodo } from './graphql/subscriptions';
window.LOG_LEVEL = 'VERBOSE';
export default {
name: 'app',
data(){
return {
todos: []
}
},
methods :{
async createNewTodo(){
const todo = { name: "Todo Title" , description: "あれをやる" + Date()}
await API.graphql(graphqlOperation(createTodo, { input: todo }))
},
async getData(){
const todoData = await API.graphql(graphqlOperation(listTodos))
this.todos.push(...this.todos, ...todoData.data.listTodos.items);
},
subscribe(){
API.graphql(graphqlOperation(onCreateTodo)).subscribe({
next: (eventData) => {
const todo = eventData.value.data.onCreateTodo;
this.todos.push(todo);
}
})
}
},
created(){
this.getData()
this.subscribe()
}
};
</script>
試しに、ブラウザを2つ開いて動作確認しましょう。片方で Todo を追加すると、もう片方にも反映されるようになっています。
このアプリケーションでは、登録したメッセージは最大で 10 件までしか表示されません。これは GraphQL API において、 listTodos query にアタッチされた resolver 内で、 limit が 10 に設定されているためです。 GraphQL API の設計についてより詳細に知りたい方は、 AWS AppSync 開発者ガイドにある「GraphQL API の設計」をご覧になってみてください。
Step 4 : アプリケーションのリリース
さあ、いよいよ開発したアプリケーションを公開してみましょう。 Amazon S3 を利用した静的 Web サイトホスティング機能を有効化します。ターミナルで、以下のコマンドを実行してください。
$ amplify add hosting
? Select the environment setup: (Use arrow keys)
❯ DEV (S3 only with HTTP)
PROD (S3 with CloudFront using HTTPS)
? hosting bucket name myamplifyproject-20190806070802-hostingbucket
? index doc for the website index.html
? error doc for the website index.html
You can now publish your app using the following command:
Command: amplify publish
$ amplify status
Current Environment: test
| Category | Resource name | Operation | Provider plugin |
| -------- | ---------------- | --------- | ----------------- |
| Hosting | S3AndCloudFront | Create | awscloudformation |
| Api | myamplifyproject | No Change | awscloudformation |
デプロイ先の環境として DEV と PROD がありますが、開発中は Amazon S3 のみを HTTP で使うDEV でもよいでしょう。本番環境では、スケーラビリティやパフォーマンス、セキュリティ、コスト効率などの面から、 Amazon CloudFront と HTTPS を利用する PROD を選択することを推奨します。
設定ができたら、 amplify publish
コマンドでコンテンツを publish してください。 amplify publish
は、 amplify push
に加えて静的コンテンツをビルドし、 Amazon S3 にアップロードして公開するためのコマンドです。
$ amplify publish
Current Environment: test
| Category | Resource name | Operation | Provider plugin |
| -------- | ---------------- | --------- | ----------------- |
| Hosting | S3AndCloudFront | Create | awscloudformation |
| Api | myamplifyproject | No Change | awscloudformation |
? Are you sure you want to continue? Yes
⠏ Updating resources in the cloud. This may take a few minutes...
(略)
DONE Build complete. The dist directory is ready to be deployed.
INFO Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html
frontend build command exited with code 0
✔ Uploaded files successfully.
Your app is published successfully.
http://myamplifyproject-20190806070802-hostingbucket-test.s3-website-us-east-1.amazonaws.com
AWS CloudFormation によるリソース作成が行われるため、完了までは時間がかかります。 publish が済んだらブラウザが立ち上がり、公開されたアプリケーションにアクセスできるようになります。これにて、全ての作業は完了です!
ハンズオン終了後にリソースを削除するには
AWS Amplify によって作成されたバックエンドリソースには、料金が発生するものがあります。必要なければ amplify delete コマンドで削除してください。
おわりに
「リアルタイムメッセージングアプリを作る」というとハードルが高そうにも思えますが、 AWS Amplify や AWS AppSync 、 Amazon DynamoDB などを活用することで、このように短時間で実装できることがわかりました。
ハンズオンに取り組んだり、 AWS のマネージドサービスを使っていて分からないことがあれば、AWS を利用中のスタートアップおよびデベロッパーのためのコワーキングおよびイベントスペース AWS Loft Tokyo の Ask An Expert(AWS のエキスパートである中の人に技術的な質問ができるカウンター)で聞いてみるのもおすすめです。
今回ご紹介した AWS Amplify & Chalice ハンズオンは、10月25日には AWS Pop-up Loft Osaka で開催します。詳しくはこちら。また、AWS Loft Tokyoでも、11月中に開催する予定なので、イベント・セミナー一覧の情報をぜひチェックしてください!