📝

Amplify tutorial (Vue.js3.2,JavaScript)

2022/03/16に公開

要約

  • ライブラリが新しい場合、公式サイト通りに行えばよいのはステップ1まで
  • 一部コマンドを叩いた結果は公式と同じ状態にはならない。でも大した問題ではない。
  • Amplify CLIでつかうコマンド(configure,init,add api,add auth,add hosting)

公式のチュートリアル
https://docs.amplify.aws/start/getting-started/installation/q/integration/vue/
を試します。

今回の全体リポジトリ
https://github.com/covasue/myamplifyproject-public

team-provider-info.jsonは公開リポジトリでは共有するなと書かれてあるので.gitignoreに追加しています。

開発環境は前回の記事を参照お願いします。
https://zenn.dev/sueyoshi/articles/20f9fb5a5c899a
この環境を使えば@aws-amplify/cliと@vue/cliがインストールされています。
この記事を書いているときのcliのバージョンは7.6.22です。

Prerequisites(Step1)

まずAmplify CLI のコマンド amplify configureでIAMユーザーを作成します。
途中Webコンソールにアクセスしますので、Webコンソールにアクセスできる準備をお願いします。

  1. amplify configureで新しいIAMユーザーを作成します。
amplify configure
  1. 対話形式で聞かれるのでガイダンス通りに入力します。
    リージョンは東京リージョン(ap-northeast-1)をお勧めします。
Specify the AWS Region
? region:  # Your preferred region 
Specify the username of the new IAM user:
? user name:  # User name for Amplify IAM user
Complete the user creation using the AWS console
  1. ブラウザが開きユーザー作成を促されます。Admini権限がデフォルトで設定されます。
    最後にAccess keyとSecret Access keyを保存しておきます。

  2. 続きを入力します。

Enter the access key of the newly created user:
? accessKeyId:  # YOUR_ACCESS_KEY_ID さきほど保存したAccess key
? secretAccessKey:  # YOUR_SECRET_ACCESS_KEY さきほど保存した Secret Access key
This would update/create the AWS Profile in your local machine
? Profile Name:  # (default) 何か名前を付けましょう。 

Successfully set up the new user.

これでStep1は完了です。
Access keyとSecret Access keyはStep2でも使います。

Set up fullstack project(Step2)

このステップではVueプロジェクトの作成、Amplify Librariesと Amplify UI Componentsのインストール,Amplify LibrariesをVueに読み込みまで行います。

@vue/cliは開発環境が前回と同じの場合、インストール済みなので飛ばします。

  1. Vue のプロジェクトを作成します。
vue create myamplifyproject 

myamplifyprojectはプロジェクト名です。
続いて、Default ([Vue 3] babel, eslint) を選択します。
公式ではDefault (Vue 3 Preview) ([Vue 3] babel, eslint)となっていますがPreview
ではないです。

? Please pick a preset: (Use arrow keys)
❯ Default  ([Vue 3] babel, eslint)  
 Default  ([Vue 2] babel, eslint)  
  Manually select features

続いて YarnかNPMを選びます。どちらでもOKです。(公式はNPMのようです)

>Use Yarn
Use NPM

選択後、しばらくプロジェクトの作成を待ちます。
作成が終了したらディレクトリに移動します。

cd myamplifyproject

正しくVueのプロジェクトが作られているか確認でサーバーを起動します。

npm run serve --open

Ctrl + Cでサーバーを止めます。

  1. Initialize a new backend

Amplify CLIのコマンド amplify initを行います。
先ほどのconfigure はどちらかというとアカウント(IAMユーザー)の作成です。
今回のinitはプロジェクトの(初期)設定です。
プロジェクトのディレクトリに移動していることを確認してからコマンドを入力しましょう
※例 root@farwq13fa:/app/myamplifyproject# amplify init

amplify init

バックエンドを作成するプロジェクト名を設定します。
リソースを作成するときの接頭語に使用されるので分かりやすい名前が望ましいです。

? Enter a name for the project (myamplifyproject) todo

上の例ではtodoと名前をつけています。
次は公式サイトと異なり下記のような表示になります。

特に変更する必要はないです。
Yを押しましょう。

続いてこのプロジェクトで使うIAMユーザーの設定を行います。
AWS profileを使うかどうか聞かれます。わたしは先ほど取得したAccess keyとSecret Access keyを使います。

? Do you want to use an AWS profile? (Y/n)

nを入力します。

? accessKeyId:  (<YOUR_ACCESS_KEY_ID>) #さきほど保存したAccess key
? secretAccessKey:  (<YOUR_SECRET_ACCESS_KEY>) #さきほど保存した Secret Access key

続いてリージョンの選択をします。

? region:  (Use arrow keys)
❯ us-east-1 
  us-east-2 
  us-west-2 
  eu-west-1 
  eu-west-2 
  eu-central-1 
  ap-northeast-1 
(Move up and down to reveal more choices)

Step1で選択したリージョンを選びましょう。東京の場合 ap-northeast-1 です。
プロジェクト内の初期化が行われます。初期化が終わるまでしばらく待ちましょう。
終わると下記処理が完了されています。

  • amplifyディレクトリが作成されます。バックエンドの定義が入っています。
  • srcディレクトリにaws-exports.jsが作成されます。
  • リポジトリで共有しないほうが良いファイルについて.gitignoreに追記されます。
  1. Install Amplify libraries
    Amplify LibrariesとAmplify UI Components(Vue3版)をインストールします。
    UI ComponentsはVue2の場合異なりますので注意しましょう。
npm install aws-amplify@4.3.15 @aws-amplify/ui-vue@2.1.3
  1. Set up frontend
    インストールしたAmplify LibrariesをVueに組み込みます。
    src/main.jsを開き下記ソースコードを追加しましょう。
src/main.js
import { createApp } from 'vue'
import App from './App.vue'
//追加ここから
import Amplify from 'aws-amplify'
import awsExports from './aws-exports'
Amplify.configure(awsExports)
//追加ここまで
createApp(App).mount('#app')

*オプション ここまでの工程がうまくいっているか確認のためにサーバーを起動してみましょう。

npm run serve --open

先ほど変わらない結果が表示されていればOKです。
次はGraphQLを使ってデータベースに接続します。

Connect API and database to the app(Step3)


このステップではAmplify CLIコマンドを使ってAWSのリソース(AppSync + DynamoDB)を作成後、Amplify Librariesを使ってリソースにアクセスし、データベースのRead/Writeを行います。
チュートリアルのメインの項目といってよいほどボリュームがあります。
Amplify CLIコマンドは amplify add (使うリソース)を設定後、amplify pushを叩くことでAWS上にリソースが作成されます。なぜいきなりAWSリソースが作成されないのかというとたぶんMock等で十分にテストを行ってあとにリソースの作成・変更をするからだと勝手に思ってます。
今回のチュートリアルではMockには触れません。

  1. Create GraphQL API and database
    Amplify CLIコマンドで amplify add apiを叩きます。
amplify add api

GraphQLを選択します。

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

公式と異なり以下のような状態になりますが特に問題なくContinueを選択します。
特に公式のようにmyapiと名前を変える必要はありません。

対話形式ですすむので以下のように選択します。

? Choose a schema template:
# Single object with fields (e.g., “Todo” with ID, name, description)
? Do you want to edit the schema now?
# Yes

最後にスキーマーを編集するをYesを選択しているので
コードエディタがgraphqlのスキーマーを開きます。
特に編集する必要はありません。

amplify/backend/api/myapi/schema.graphql
type Todo @model {
  id: ID!
  name: String!
  description: String
}

@modelと書くことにより、DynamoDBにテーブルが作成されgraphQL(AppSync)を解して操作するようになります。

  1. Deploy your GraphQL API

Amplify CLIコマンド amplify push を叩くことによりAWS上に構築をします。
しばらく待つと
3.Generate frontend code for the GraphQL API に進みます。

amplify push
  1. Generate frontend code for the GraphQL API

いくつか対話形式で聞かれるので同じように入力します。

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)

処理が終わるまでしばらく待ちます。
処理が終わったら正常におこなわれているかAmplify CLIでamplify statusで状況を確認します。

amplify status

以下と同じ表示であればOKです。

Current Environment: dev

| Category | Resource name | Operation | Provider plugin   |
| -------- | ------------- | --------- | ----------------- |
| Api      | todo          | No Change | awscloudformation |
  1. Connect frontend to API

graphqlを使ってDynamoDBをRead/Writeする処理をコーディングします。
Vue(src/App.vue)を編集しましょう。

最初にcreateTodoを使ってTodoを入力できる機能を作ります。
この時点では入力の機能のみです。

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

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

export default {
  name: 'app',
  data() {
    return {
      name: '',
      description: ''
    }
  },
  methods: {
    async createTodo() {
      const { name, description } = this;
      if (!name || !description) return;
      const todo = { name, description };
      await API.graphql({
        query: createTodo,
        variables: {input: todo},
      });
      this.name = '';
      this.description = '';
    }
  }
};
</script>

サーバーを立ち上げて、動作確認します。

npm run serve 

入力できることを確認したらCtrl + cでサーバーを停止します。

  1. Reading data with GraphQL queries

続いてlistTodosを使って入力した内容を表示します。

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';

export default {
  name: 'App',
  async created() {
    this.getTodos();
  },
  data() {
    return {
      name: '',
      description: '',
      todos: []
    }
  },
  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;
    }
  }
}
</script>

こちらも先ほどと同じように正しく動いているか確認しましょう。
4.で入力した内容が表示されます。

  1. Real-time data with GraphQL subscriptions

最後にサブスクリプションの例を掲載します。
onCreateTodoを使った公式HPの形にのっとると以下のようなコードになるかと思います。
メソッド:createTodoから新しい値を配列を入れずに、サブスクリプションを使って変更をキャッチする仕組みになっています。

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';
// other imports
import { onCreateTodo } from './graphql/subscriptions';
export default {
  name: 'app',
  async created() {
    this.getTodos();
    // other functions and properties
    this.subscribe();
  },
  data() {
    return {
      name: '',
      description: '',
      todos: []
    }
  },
  methods: {
    async createTodo() {
      const { name, description } = this;
      if (!name || !description) return;
      const todo = { name, description };
      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;
    },
    // other methods
    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>

Add authentication(Step4)

このステップでは認証を構築します。Amplify CLIで認証を作成後、Amplify UI Componentsを使って爆速で認証コンポーネントを作成します。

  1. Create authentication service

Amplify CLIコマンドで amplify add authを叩きます。

amplify add auth

以下の通り対話形式の選択を行ってください。
これによりAWS Cognitoを認証プロバイダーとして使用できます。
Cognitoはユーザーの登録、認証、パスワードの設定など堅牢なユーザー管理サービスを提供します。

? Do you want to use the default authentication and security configuration? Default configuration
? How do you want users to be able to sign in? Username
? Do you want to configure advanced settings?  No, I am done.

apiの時と同じく、Amplify CLIコマンド amplify push を叩くことによりAWS上に構築をします。

amplify push

続いて対話形式で処理を続けるか聞かれるのでYesを選択してください。

? Are you sure you want to continue? Y
  1. Create login UI

公式のチュートリアルのソースコードはStep3を無視した形なのといきなりVue3の新機能であるsetupを使っているので、まずは今まで通りOptions APIを使って実装してみます。
以下がソースコード例になります。

src/App.vue
<template>
  <div id="app">
    <authenticator>
      <template v-slot="{ user, signOut }">
        <h1>Hello {{ user.username }}!</h1>
        <button @click="signOut">Sign Out</button>
        <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>
      </template>
    </authenticator>
  </div>
</template>

<script>
import { API } from 'aws-amplify';
import { createTodo } from './graphql/mutations';
import { listTodos } from './graphql/queries';
import { onCreateTodo } from './graphql/subscriptions';
import { Authenticator } from '@aws-amplify/ui-vue';
import '@aws-amplify/ui-vue/styles.css';
export default {
  name: 'app',
  async created() {
    this.getTodos();
    this.subscribe();
  },
  data() {
    return {
      name: '',
      description: '',
      todos: []
    }
  },
  components: {
    Authenticator
  },
  methods: {
    async createTodo() {
      const { name, description } = this;
      if (!name || !description) return;
      const todo = { name, description };
      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>

Amplify UI ComponentsのAuthenticatorを使います。
authenticatorタグで挟むことにより、認証機能が実装されます。
認証後に今までの画面が表示されることになります。
サーバーを立ち上げて動作確認をしましょう。

npm run serve


上記の画面が表示されます。
右のCreate Accountタブをクリックしてアカウントを作成しましょう。

入力したメールアドレスに認証コードなどが行われ、メールアドレスの確認が取れるとアカウント登録は完了です。
ログインはメールアドレスではなくUsernameなので気を付けましょう。
今まで通りの画面が表示されたらOKです。
続いてSetupを使用した例です。

src/App.vue
<template>
  <div id="app">
    <authenticator>
      <template v-slot="{ user, signOut }">
        <h1>Hello {{ user.username }}!</h1>
        <button @click="signOut">Sign Out</button>
        <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="clickCreateTodo">Create Todo</button>
        <div v-for="item in todos" :key="item.id">
          <h3>{{ item.name }}</h3>
          <p>{{ item.description }}</p>
        </div>
      </template>
    </authenticator>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { API } from 'aws-amplify';
import { createTodo } from './graphql/mutations';
import { listTodos } from './graphql/queries';
import { onCreateTodo } from './graphql/subscriptions';
import { Authenticator } from '@aws-amplify/ui-vue';
import '@aws-amplify/ui-vue/styles.css';
const name = ref(''),
  description = ref(''),
  todos = ref([]);
const clickCreateTodo = async () => {
  if (!name.value || !description.value) return;
  const todo = { name: name.value, description: description.value };
  await API.graphql({
    query: createTodo,
    variables: { input: todo },
  });
  name.value = '';
  description.value = '';
};
const getTodos = async () => {
  const todosData = await API.graphql({
    query: listTodos
  });
  todos.value = todosData.data.listTodos.items;
};
const 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];
      }
    });
};
getTodos();
subscribe();
</script>

Deploy and host app(Step5)

最後にAmplify Hostingを使ってWebサービスをインターネットに公開します。(ホストにデプロイします。)

  1. Add hosting to your app
    Amplify CLIコマンドで amplify add hostingを叩きます。
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
  1. Publish your app
    Amplify CLIコマンドで amplify publishでWebサイトを公開します。

pushではないので注意しましょう。

amplify publish

しばらく待つと。
(任意の文字列).amplifyapp.comでwebサイトが公開されます。
ブラウザで開いて動作を確認しましょう。

Step4で作成したユーザーでログインしましょう。
今まで作成したTodoリストが表示されるはずです。
これはAWSリソース(Cognito,DynamoDB)を使っているので同じ内容になります。
IAMユーザーを作るとき以外はAWSのコンソールに入ることなくDBを使い、認証を伴う、WEBサービスを作成することが確認できたと思います。
おめでとうございます!

ある程度確認して満足したらさみしいですが
Amplify CLIコマンドの amplify deleteでAWSリソースを削除します。

amplify delete

本当に削除してよいですか?と対話形式で聞かれるのでYを選択しましょう。
アプリケーションに使ったすべてのリソースが削除されます。
とても便利ですね。
※IAMユーザーは消えてないので必要がなければ削除しましょう。

Next steps

今度はamplify storageを使ったサンプルを書く予定です。

Discussion