AWS Amplify + Vue.js 3.0チュートリアルをやってみた

今年2月に、AWS AmplifyでVue.js 3.0がサポートされました。

どんな感じなのかな〜と気になっていたところ、公式っぽいチュートリアルを発見したので、やっていこうじゃないかというわけです。

はじめに(Getting Started)

このチュートリアルでは、バックエンドをセットアップし、Webアプリに統合するまでガイドしていきます。TodoアプリをGraphQL APIで作成し、クラウド・データベースからアイテムを保存・取得し、リアルタイム・サブスクリプションを通してアップデートを受けとっていきます。

前提要件(Prerequisites)

初めに以下をインストールします。AWSアカウントをもっていない場合は、AWSのサインアップも必要です。

  • Node.js v12.x or later
  • npm v5.x or later
  • git v2.14.1 or later

今回の使用端末はmacOS Big Sur 11.4で、各バージョンは以下の状態でした。

$ npm -v
6.14.8
$ node -v
v14.13.1
$ git --version
git version 2.30.2

npmでAmplifyのCLIをインストールします。うまくいかない場合はsudoをつけてみてください。

$ npm install -g @aws-amplify/cli

Amplifyを設定してきます。amplify configureを実行すると、まずはAWSアカウントへのサインインを促されます。

$ 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/

使用するアカウントにサインインした後、リージョンやIAM User名を設定します。その後、AWSコンソールへ飛ばされます。

Press Enter to continue

Specify the AWS Region
? region:  ap-northeast-1
Specify the username of the new IAM user:
? user name:  XXXXXXXXXX
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=XXXXXXXXXX&permissionType=policies&policies=arn:aws:iam::aws:policy%2FAdministratorAccess

IAM User名が入力されていることを確認し、そのまま次のステップをクリックします。

AdministratorAccessにチェックが入っていることを確認し、そのまま次のステップをクリックします。タグ等は入力しなくて大丈夫です。

最終的に出力された画面にアクセスキーIDとシークレットアクセスキーがあるので、それをコピーしてCLIに貼り付けます。

キーを入力し、プロファイルを指定したらセットアップ完了です。

Press Enter to continue

Enter the access key of the newly created user:
? accessKeyId:  ********************
? secretAccessKey:  ****************************************
This would update/create the AWS Profile in your local machine
? Profile Name:  angel

Successfully set up the new user.

フルスタック・プロジェクトのセットアップ(Set up fullstack project)

続いて、Vueの環境をVue CLIでインストールしていきます。npmでVue CLIをインストールし、vue create myamplifyprojectでVue 3の環境を構築します。

$ npm install -g @vue/cli
...
$ vue create myamplifyproject
Vue CLI v4.5.13
? Please pick a preset: 
  Default ([Vue 2] babel, eslint) 
❯ Default (Vue 3) ([Vue 3] babel, eslint) 
  Manually select features

Vue3.0の環境が完了したら、ディレクトリの中に入り、モジュールをインストールします。

$ cd myamplifyproject
$ npm install

npm runでサーバーを立ち上げて、http://localhost:8080/でVueお馴染みの画面が立ち上がればOKです。

$ npm run serve --open

続いてAmplifyの初期設定を行なっていきます。myamplifyprojectディレクトリ配下でamplify initを実行します。

$ amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project myamplifyproject
The following configuration will be applied:

Project information
| Name: myamplifyproject
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: vue
| Source Directory Path: src
| Distribution Directory Path: dist
| Build Command: npm run-script build
| Start Command: npm run-script serve

? Initialize the project with the above configuration? No

基本的にデフォルトのままで大丈夫ですが、当方Vimを使っているのでそこだけ変えました。

? Enter a name for the environment dev
? Choose your default editor: Vim (via Terminal, Mac OS only)
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using vue
? Source Directory Path:  src
? Distribution Directory Path: dist
? Build Command:  npm run-script build
? Start Command: npm run-script serve
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 angel

MFAを設定しているプロファイルであればMFAトークンコードを聞かれるので入力します。

Profile angel is configured to assume role
  arn:aws:iam::XXXXXXXXXXXX:role/XXXXXXXXXXXX
It requires MFA authentication. The MFA device is
  arn:aws:iam::XXXXXXXXXXXX:mfa/XXXXXXXXXXXXX
? Enter the MFA token code: 944389
Adding backend environment dev to AWS Amplify Console app: d1ocynkzs01s1y

特に問題なければ、CloudFormationのスタックが自動で立ち上がります。

⠙ Initializing project in the cloud...

CREATE_IN_PROGRESS amplify-myamplifyproject-dev-230446 AWS::CloudFormation::Stack Mon Jul 05 2021 23:05:05 GMT+0900 (日本標準時) User Initiated
CREATE_IN_PROGRESS UnauthRole                          AWS::IAM::Role             Mon Jul 05 2021 23:05:09 GMT+0900 (日本標準時)               
CREATE_IN_PROGRESS AuthRole                            AWS::IAM::Role             Mon Jul 05 2021 23:05:09 GMT+0900 (日本標準時)               
CREATE_IN_PROGRESS DeploymentBucket                    AWS::S3::Bucket            Mon Jul 05 2021 23:05:09 GMT+0900 (日本標準時)               
⠸ Initializing project in the cloud...

CREATE_IN_PROGRESS UnauthRole AWS::IAM::Role Mon Jul 05 2021 23:05:10 GMT+0900 (日本標準時) Resource creation Initiated
⠙ Initializing project in the cloud...

CREATE_IN_PROGRESS AuthRole         AWS::IAM::Role  Mon Jul 05 2021 23:05:10 GMT+0900 (日本標準時) Resource creation Initiated
CREATE_IN_PROGRESS DeploymentBucket AWS::S3::Bucket Mon Jul 05 2021 23:05:11 GMT+0900 (日本標準時) Resource creation Initiated
⠹ Initializing project in the cloud...

CREATE_COMPLETE UnauthRole AWS::IAM::Role Mon Jul 05 2021 23:05:29 GMT+0900 (日本標準時) 
CREATE_COMPLETE AuthRole   AWS::IAM::Role Mon Jul 05 2021 23:05:29 GMT+0900 (日本標準時) 
⠹ Initializing project in the cloud...

CREATE_COMPLETE DeploymentBucket AWS::S3::Bucket Mon Jul 05 2021 23:05:33 GMT+0900 (日本標準時) 
⠼ Initializing project in the cloud...

CREATE_COMPLETE amplify-myamplifyproject-dev-230446 AWS::CloudFormation::Stack Mon Jul 05 2021 23:05:35 GMT+0900 (日本標準時) 
✔ Successfully created initial AWS cloud resources for deployments.
✔ Initialized provider successfully.
Initialized your environment successfully.

Your project has been successfully initialized and connected to the cloud!

マネジメントコンソールからもスタックが構築できてることが確認できました。

最後に、Amplify関連のモジュールをインストールしていきます。

$ npm install aws-amplify @aws-amplify/ui-components

環境構築は以上で完了です。フロントエンドからバックエンドへやりとりするために、src/main.jsを以下のコードで書き換えます。

import { createApp } from 'vue'
import App from './App.vue'
import Amplify from 'aws-amplify';
import aws_exports from './aws-exports';
import {
  applyPolyfills,
  defineCustomElements,
} from '@aws-amplify/ui-components/loader';

Amplify.configure(aws_exports);
applyPolyfills().then(() => {
  defineCustomElements(window);
});

createApp(App).mount('#app')

以降でTodoアプリのコードを追記していきます。

APIとデータベースをAppに接続する(Connect API and database to the app)

この章でTodoリストの作成と、Todoに対してcreate/update/deleteができるようにコーディングしていきます。まず初めに、amplify add apiを実行しGraphQL APIを作成します。以下のようにパラメータを設定していってください。最後に「スキーマを編集しますか?」と聞かれるので、試しに中身を見てみましょう。

$ amplify add api
? Please select from one of the below mentioned services: GraphQL
? Provide API name: myapi
? Choose the default authorization type for the API API key
? Enter a description for the API key: demo
? After how many days from now the API key should expire (1-365): 7
? Do you want to configure advanced settings for the GraphQL API No, I am done.
? Do you have an annotated GraphQL schema? No
? Choose a schema template: Single object with fields (e.g., “Todo” with ID, name, description)

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/auth


GraphQL schema compiled successfully.

Edit your schema at /Users/home/myamplifyproject/amplify/backend/api/myapi/schema.graphql or place .graphql files in a directory at /Users/home/myamplifyproject/amplify/backend/api/myapi/schema
? Do you want to edit the schema now? Yes

スキーマ情報はamplify/backend/api/myapi/schema.graphqlに入っており、以下のようにID、Name、Descriptionがデフォルトで定義されています。チュートリアルでは特に編集しなくて大丈夫です。

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

APIが作成できたので、amplify pushして反映させます。デフォルトのままパラメータを指定していき、入力が完了するとCloudFormationのネストされたスタックがいくつか作成されます。

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

Current Environment: dev

| Category | Resource name | Operation | Provider plugin   |
| -------- | ------------- | --------- | ----------------- |
| Api      | myapi         | Create    | awscloudformation |
? Are you sure you want to continue? Yes

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/auth


GraphQL schema compiled successfully.

Edit your schema at /Users/home/myamplifyproject/amplify/backend/api/myapi/schema.graphql or place .graphql files in a directory at /Users/home/myamplifyproject/amplify/backend/api/myapi/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
⠦ Updating resources in the cloud. This may take a few minutes...

amplify statusを実行すると、現在のスタックの状態やAPIキーなどを参照できます。

$ amplify status
Current Environment: dev

| Category | Resource name | Operation | Provider plugin   |
| -------- | ------------- | --------- | ----------------- |
| Api      | myapi         | No Change | awscloudformation |

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

続いて、フロントエンドをAPIに接続させます。src/App.vueを開いて、以下のコードで上書きしてください。

<template>
  <div id="app">
    <h1>Todo App</h1>
    <input type="text" v-model="name" placeholder="Todo name">
    <input type="text" v-model="description" placeholder="Todo description">
    <button v-on:click="createTodo">Create Todo</button>
    <div v-for="item in todos" :key="item.id">
      <h3>{{ item.name }}</h3>
      <p>{{ item.description }}</p>
    </div>
  </div>
</template>

<script>
import { API } from 'aws-amplify';
import { createTodo } from './graphql/mutations';
import { listTodos } from './graphql/queries';
import { onCreateTodo } from './graphql/subscriptions';

export default {
  name: 'App',
  data() {
    return {
      name: '',
      description: '',
      todos: []
    }
  },
  created(){
    this.getTodos();
    this.subscribe();
  },
  methods: {
    async createTodo() {
      const { name, description } = this;
      if (!name || !description) return;
      const todo = { name, description };
      this.todos = [...this.todos, todo];
      await API.graphql({
        query: createTodo,
        variables: {input: todo},
      });
      this.name = '';
      this.description = '';
    },
    async getTodos() {
      const todos = await API.graphql({
        query: listTodos
      });
      this.todos = todos.data.listTodos.items;
    },
    subscribe() {
      API.graphql({ query: onCreateTodo })
        .subscribe({
          next: (eventData) => {
            let todo = eventData.value.data.onCreateTodo;
            if (this.todos.some(item => item.name === todo.name)) return; // remove duplications
            this.todos = [...this.todos, todo];
          }
        });
    }
  }
}
</script>

サーバーを立ち上げると、Todo Appが表示されました。上記のコードを読めばわかることではありますが、Todoは追加のみで、消去や更新はできないみたいです。

認証を追加する(Add authentication)

Amplifyでは、Amazon Cognitoを使って簡単に認証機能を実装することができます。amplify add authを実行して設定していきましょう。

$ 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 myamplifyproject697f2705 locally

amplify pushで、サービスをデプロイします。これによって、CloudFormationリソースが計2つとなります。

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

Current Environment: dev

| Category | Resource name            | Operation | Provider plugin   |
| -------- | ------------------------ | --------- | ----------------- |
| Auth     | myamplifyproject697f2705 | Create    | awscloudformation |
| Api      | myapi                    | No Change | awscloudformation |
? Are you sure you want to continue? Yes

最後に、src/App.vueにログイン画面の機能を追加します。<template>のタグの中を<amplify-authenticator>で囲い、末尾に<amplify-sign-out></amplify-sign-out>を追加するだけでOKです。

<template>
  <amplify-authenticator>
    <div id="app">
      <h1>Todo App</h1>
      <input type="text" v-model="name" placeholder="Todo name">
      <input type="text" v-model="description" placeholder="Todo description">
      <button v-on:click="createTodo">Create Todo</button>
      <div v-for="item in todos" :key="item.id">
        <h3>{{ item.name }}</h3>
        <p>{{ item.description }}</p>
      </div>
    </div>
    <amplify-sign-out></amplify-sign-out>
  </amplify-authenticator>
</template>

npm run serveでサーバー立ち上げると、サインアップ用の画面が表示されます。

Create accountでアカウント新規作成すると、設定したメールアドレスに認証コードが届きます。認証コードを画面に入力すればアカウントセットアップ完了です。

デプロイしてAppをホストする(Deploy and host app)

最後に、Appをデプロイしてホストします。

$ 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

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

Current Environment: dev

| Category | Resource name            | Operation | Provider plugin   |
| -------- | ------------------------ | --------- | ----------------- |
| Hosting  | amplifyhosting           | Create    | awscloudformation |
| Api      | myapi                    | No Change | awscloudformation |
| Auth     | myamplifyproject68154b13 | 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
      
✔ Zipping artifacts completed.
✔ Deployment complete!
https://dev.XXXXXXXXX.amplifyapp.com

出力されたURLをブラウザから開くと、Appがホストされていることが確認できました。先ほど作成したアカウントでログインできます。

次のステップ(Next steps)

これでチュートリアルは終わりです。以下のコマンドを叩き、環境の削除を忘れないでください。

$ amplify delete
? Are you sure you want to continue? This CANNOT be undone. (This will delete all the environments of the project from the cloud and wipe out all the local files created by Amplify CLI) Yes
⠋ Deleting resources from the cloud. This may take a few minutes...

このチュートリアルの次のステップということで、以下があげられていました。

  • Authentication
  • DataStore
  • User File Storage
  • Serverless APIs
  • Analytics
  • AI/ML
  • Push Notification
  • PubSub
  • AR/VR

色々なタイプのアプリが作れるみたいですね!興味がある分野を深掘ってみてください。