#mynavi(AWSメモ)
#setlinebreak(on);

* 概要 [#m18a5639]
#html(<div style="padding-left: 10px;">)
AWS amplify を使用してSPAのプロトタイピングを行う場合の覚書。
尚、今回はクライアントには vue.js を使用した。
#html(</div>)

* 所感 [#gfea250f]
#html(<div style="padding-left: 10px;">)
ログイン認証から簡単なAPIを叩く所までをサラッと触ってみたが、簡単なコマンドベースで一通り構築から公開できる為、最初のプロトタイピングで使用する分には有用であると感じた。
尚、本記事にはログイン機能は記載していないが、「amplify add auth」及び「amplify push」して、提供されている認証用コンポーネント(※)を使用するだけで Cognito 周りも簡単に利用できる。
※1 ... https://aws-amplify.github.io/docs/js/vue#amplifyplugin

ただ、本開発では CloudFormationテンプレートが必要になる等、CICD等の諸々の考慮が必要になる為、そのまま本開発でも使用するかどうかは要検討。
( amplify-cli で構築すると一通りのリソースがネストされたスタックとして作成される為、スタックからのテンプレート取得等はある程度可能)
#html(</div>)


* 目次 [#uf9a3a47]
#contents
- 関連
-- [[AWSメモ]]
-- [[Vue.js]]
-- [[GraphQL入門]]
//-- [[AWS Amplifyのコンポーネントを使ってみる]]
- 参考ドキュメント
-- [[AWS Amplify コンソールユーザーガイド >https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/welcome.html]]
-- [[AWS Amplify CLI>https://github.com/aws-amplify/amplify-cli]]
-- https://aws-amplify.github.io/docs/cli-toolchain/quickstart?sdk=js
-- https://aws-amplify.github.io/docs/
-- https://aws-amplify.github.io/docs/js/vue

* クライアントの実装 [#u3a9dea1]
#html(<div style="padding-left: 10px;">)

クライアント側の実装を行っておく。

** vueプロジェクトの作成 [#n373112f]

以下の通り作成
#myterm2(){{
vue create amplify-project1

? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Linter
? Use history mode for router? (Requires proper server setup for index fallback in production) No     ※1
? Pick a linter / formatter config: Basic
? Pick additional lint features: (Press  to select,  to toggle all,  to invert selection)Lint on save
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? (y/N) n
}}

** クライアント側の実装 [#u6c0e122]

一覧取得を行う簡単な画面を作成する。

まずは作成したプロジェクトディレクトリに移動。
#myterm2(){{
cd amplify-project1
}}


App.js
#mycode2(){{
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link> |
      <router-link to="/sample1">Sample1</router-link>   // 追加
    </div>
    <router-view/>
  </div>
</template>
:
}}

router/index.js
#mycode2(){{
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [ 
  { path: '/', name: 'home', component: Home },
  { path: '/about', name: 'about', component: () => import('../views/About.vue') },
  { path: '/sample1', name: 'sample1', component: () => import('../views/Sample1.vue') }  // 追加
]

const router = new VueRouter({
  routes
})

export default router
}}

一覧画面のデータ取得部分は、いったん空で以下の通り実装しておく。

src/views/Sample1.vue
#mycode2(){{
<template>
  <div class="sample1">
    <h1>This is sample page</h1>
    <table id="sample1_table" v-if="items.length > 0">
     <thead>
      <tr>
          <th>Name</th><th>Price</th>
      </tr>
      </thead>
      <tbody>
      <tr v-for="item in items" v-bind:key="item.name">
        <td>&#123;&#123; item.name &#125;&#125;</td><td>&#123;&#123; item.price &#125;&#125;</td>
      </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  name: 'sample1',
  data: function(){
    return {
      items: []
    }
  },
  created: function(){
    this.getItems()
  },
  methods: {
    getItems: function(){
      console.log("getItems!")
      // TODO: 実装
    }
  }
}
</script>
}}

#html(</div>)

* amplifyの使用準備 [#id3abdce]
#html(<div style="padding-left: 10px;">)

** CLIのインストール [#o8db76c3]
#myterm2(){{
npm install -g @aws-amplify/cli
}}

** amplify用のAWSユーザプロファイルのセットアップ [#y1df7d17]
#myterm2(){{
amplify configure
}}
※ 表示された手順に従ってIAMユーザを作成する。

//** amplify 及び amplify-vue のインストール [#mac4308a]
//
//#myterm2(){{
//npm i aws-amplify
//npm i aws-amplify-vue
//}}
//
//&br;

#html(</div>)

* amplifyプロジェクトの作成 [#va98c63b]
#html(<div style="padding-left: 10px;">)

amplify-cli でプロジェクトを以下の通り初期化。(先程の作成した vue.js のプロジェクト直下でコマンドを実行)
#myterm2(){{
amplify init

Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project amplify-project1
? 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

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html

? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use amplify1
&#10297; Initializing project in the cloud...

CREATE_IN_PROGRESS DeploymentBucket                    AWS::S3::Bucket            Tue Oct 22 2019 00:01:57 GMT+0900 (日本標準時) Resource creation Initiated
CREATE_IN_PROGRESS UnauthRole                          AWS::IAM::Role             Tue Oct 22 2019 00:01:57 GMT+0900 (日本標準時) Resource creation Initiated
CREATE_IN_PROGRESS AuthRole                            AWS::IAM::Role             Tue Oct 22 2019 00:01:57 GMT+0900 (日本標準時) Resource creation Initiated
CREATE_IN_PROGRESS DeploymentBucket                    AWS::S3::Bucket            Tue Oct 22 2019 00:01:55 GMT+0900 (日本標準時)                            
CREATE_IN_PROGRESS AuthRole                            AWS::IAM::Role             Tue Oct 22 2019 00:01:55 GMT+0900 (日本標準時)                            
CREATE_IN_PROGRESS UnauthRole                          AWS::IAM::Role             Tue Oct 22 2019 00:01:55 GMT+0900 (日本標準時)                            
CREATE_IN_PROGRESS amplify-project1-dev-20191022000151 AWS::CloudFormation::Stack Tue Oct 22 2019 00:01:53 GMT+0900 (日本標準時) User Initiated             
&#10278; Initializing project in the cloud...

CREATE_COMPLETE DeploymentBucket AWS::S3::Bucket Tue Oct 22 2019 00:02:18 GMT+0900 (日本標準時) 
&#10278; Initializing project in the cloud...

CREATE_COMPLETE amplify-project1-dev-20191022000151 AWS::CloudFormation::Stack Tue Oct 22 2019 00:02:22 GMT+0900 (日本標準時) 
CREATE_COMPLETE AuthRole                            AWS::IAM::Role             Tue Oct 22 2019 00:02:19 GMT+0900 (日本標準時) 
CREATE_COMPLETE UnauthRole                          AWS::IAM::Role             Tue Oct 22 2019 00:02:19 GMT+0900 (日本標準時) 
&#10004; Successfully created initial AWS cloud resources for deployments.
&#10004; Initialized provider successfully.
Initialized your environment successfully.

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

Some next steps:
"amplify status" will show you what you've added already and if it's locally configured or deployed
"amplify <category> add" will allow you to add features like user login or a backend API
"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

Pro tip:
Try "amplify add api" to create a backend API and then "amplify publish" to deploy everything

}}
&br;
#html(</div>)

* サーバ側の処理作成 [#ld8708bb]
#html(<div style="padding-left: 10px;">)

** Lambda関数の作成 [#r1572a7b]

ここでは GetItemsSample1 という名前で作成した。
#myterm2(){{
amplify add function

Using service: Lambda, provided by: awscloudformation
? Provide a friendly name for your resource to be used as a label for this category in the project: GetItemsSample1
? Provide the AWS Lambda function name: GetItemsSample1
? Choose the function template that you want to use: Hello world function
? Do you want to access other resources created in this project from your Lambda function? Yes
? Select the category (Press &lt;space&gt; to select, &lt;a&gt; to toggle all, &lt;i&gt; to invert selection)

You can access the following resource attributes as environment variables from your Lambda function
var environment = process.env.ENV
var region = process.env.REGION

? Do you want to edit the local lambda function now? No
Successfully added resource GetItemsSample1 locally.

Next steps:
Check out sample function code generated in <project-dir>/amplify/backend/function/GetItemsSample1/src
"amplify function build" builds all of your functions currently in the project
"amplify function invoke GetItemsSample1" enables you to test a function locally
"amplify push" builds all of your local backend resources and provisions them in the cloud
"amplify publish" builds all of your local backend and front-end resources (if you added hosting category) and provisions them in the cloud
}}

** Lambda関数の編集 [#j7b9d098]

生成されているファイルを以下の通り編集する。

amplify/backend/function/GetItemsSample1/src/index.js
#mycode2(){{
exports.handler = function (event, context) {
  const response = {
  	statusCode: 200,
  	headers: {
  		"Access-Control-Allow-Origin": "*",
  	},
  	body: JSON.stringify({
  		items: [
  			{name: "sample1", price: 1000},
  			{name: "sample2", price: 2000},
  			{name: "sample3", price: 3000},
  		]
  	})
  }
  console.log(response);
  context.done(null, response);
};
}}

** API gatewayの追加 [#n5ac4007]

作成したLambdaを呼び出す為のAPI Gatewayを追加する。

#myterm2(){{
amplify add api

? Please select from one of the below mentioned services REST
? Provide a friendly name for your resource to be used as a label for this category in the project: GetItemsSample1Api
? Provide a path (e.g., /items) /items
? Choose a Lambda source Use a Lambda function already added in the current Amplify project
? Choose the Lambda function to invoke by this path GetItemsSample1
? Restrict API access Yes
? Who should have access? Authenticated and Guest users
? What kind of access do you want for Authenticated users? read
? What kind of access do you want for Guest users? read
Successfully added auth resource locally.
? Do you want to add another path? No
Successfully added resource GetItemsSample1Api 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
}}

&br;
#html(</div>)


* クライアント処理の修正 [#p735f43c]
#html(<div style="padding-left: 10px;">)

ここからは実際にamplifyのモジュールを使用してAPIアクセスを行うようにクライアント側を修正していく。

** amplify用のクライアントモジュールをインストール [#ice4239a]
#myterm2(){{
npm i aws-amplify
npm i aws-amplify-vue
}}
※ https://aws-amplify.github.io/docs/js/vue

** main.js の修正 [#z04da32d]
#mycode2(){{
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// 追加(ここから)
import Amplify, * as AmplifyModules from 'aws-amplify'
import { AmplifyPlugin } from 'aws-amplify-vue'
import awsconfig from './aws-exports'
Amplify.configure(awsconfig)
Vue.use(AmplifyPlugin, AmplifyModules)
// 追加(ここまで)

Vue.config.productionTip = false

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')
}}
※ https://aws-amplify.github.io/docs/js/vue

** API通信部分の実装 [#sf5a29cf]

各コンポーネント等では this.$Amplify.API を使用して amplify の API を利用する事ができる。
※ https://aws-amplify.github.io/docs/js/api#using-the-api-client

src/views/Sample1.vue
#mycode2(){{
<template>
  <div class="sample1">
    <h1>This is sample page</h1>
    <table id="sample1_table" v-if="items.length > 0">
     <thead>
      <tr>
          <th>Name</th><th>Price</th>
      </tr>
      </thead>
      <tbody>
      <tr v-for="item in items" v-bind:key="item.name">
        <td>&#123;&#123; item.name &#125;&#125;</td><td>&#123;&#123; item.price &#125;&#125;</td>
      </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  name: 'sample1',
  data: function(){
    return {
      items: []
    }
  },
  created: function(){
    this.getItems()
  },
  methods: {
    getItems: function(){
      const self = this;
      // this.$Amplify.API を使用して、作成したAPI にアクセス
      this.$Amplify.API.get("GetItemsSample1Api", "/items").then(response => {
        self.items = response.items;
      }).catch(error => {
        console.error(error.response)
      });

    }
  }
}
</script>
}}

#html(</div>)


* 動作確認 [#n2e8f793]
#html(<div style="padding-left: 10px;">)

普通にローカルで vue を起動して動作確認。

#myterm2(){{
npm run serve
}}

&br;
#html(</div>)


* インターネットへの公開 [#jccc793d]
#html(<div style="padding-left: 10px;">)

** S3ホスティングバケット/設定の追加 [#t8d02ab8]
#myterm2(){{
amplify add hosting
? Select the environment setup: DEV (S3 only with HTTP)
? hosting bucket name amplify-project1-20191022155632-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
}}

** 公開 [#h40126f4]
#myterm2(){{
amplify publish
}}
※ 他端末からも表示されたURLにブラウザからアクセス可能となる。

&br;
#html(</div>)

* Amplifyのコンポーネント/API [#p4007f4f]
#html(<div style="padding-left: 10px;">)

ログイン画面用のコンポーネントや通信用のAPIなどが利用できる。
※詳細は割愛。

https://aws-amplify.github.io/docs/js/vue

#html(</div>)


* amplify-cli メモ [#pab425c7]
#html(<div style="padding-left: 10px;">)

| コマンド          | 説明 |h
| amplify configure | |
| amplify init | |
| amplify add <category> | |
| amplify update <category> | |
| amplify push | |
| amplify publish | |
| amplify serve | |
| amplify delete | |
| amplify status | |
※ https://github.com/aws-amplify/amplify-cli#commands-summary

#html(</div>)

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS