AWS Amplify + Vue.jsでサーバレスアプリ開発 vol.3

# 概要
こちらの記事を参考に、サーバーレスでwebアプリ開発をしたメモシリーズの2つ目です。
https://qiita.com/minato-naka/items/7b445bcf0794189e65a0

[vol.1](https://qiita.com/yuukieiu/items/c9681d6e0287e351f0aa)
[vol.2](https://qiita.com/yuukieiu/items/738f8b0803c673ac3e72)

# Hostingでアプリ公開＆自動デプロイ実装編
vol.2の終わりに書いた通り、[⑥ Hostingでアプリ公開＆自動デプロイ実装編](https://qiita.com/minato-naka/items/3123950aa852ee3250fe)になります。

## AmplifyのHostingで自動デプロイ設定
今回は自前のGitHubリポジトリを用意して、そこからデプロイするようにします。
ここまでリポジトリを用意しないまま進んできたので、用意してコミットしておきます。

Hostingを使用するようコマンド実行します。
```sh
>amplify add hosting
? Select the plugin module to execute ...  (Use arrow keys or type to filter)
❯ Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
  Amazon CloudFront and S3
? Choose a type
> Continuous deployment (Git-based deployments) 
  Manual deployment
  Learn more
```

## リポジトリブランチの追加
ここまで入力するとブラウザでAWSコンソールが開きます。
僕の場合はBackend environmentが表示されていたので…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/c7b7621f-2e52-9eed-77e5-bd061e481f7a.png)
・「Hosing environments」のタブを開く
・「GitHub」を選択
・「ブランチを接続」をクリック
しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/08d0d231-10db-2b76-c84c-42fba3abef9f.png)
GitHubの認証をしたら、GitHub側にAWSからのアクセスを許可する設定をします。
Repository accessはOnly select repositoriesにした方が気持ちが穏やかかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/92930536-fdf4-99e0-3ba4-d221141277ea.png)
AWSコンソールでリポジトリやブランチを設定して次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/39f1562a-fa50-9669-138c-31dbf09afc48.png)

## ビルド設定の構成
「このブランチで使用するバックエンド環境を選択」の「Environment」を「dev」を選択します。
「amplifyconsole-backend-role」は参考ページのそのまま作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/9ed4d20b-5719-163a-0eb6-b4818a87dc7a.png)

## 確認
内容を確認して保存してデプロイ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/4ab808fc-1fa5-c52b-4258-4244f708054e.png)

## デプロイ失敗
デプロイ失敗したのでログを確認。
ESLintのルールで怒られている。
```
2022-05-22T09:32:00.494Z [INFO]: ERROR  Failed to compile with 1 error9:31:59 AM
2022-05-22T09:32:00.495Z [INFO]: /codebuild/output/src038903468/src/flowing-leaves/src/main.js
                                 7:8  error  Identifier 'aws_exports' is not in camel case  camelcase
                                 ✖ 1 problem (1 error, 0 warnings)
                                 You may use special comments to disable some warnings.
                                 Use // eslint-disable-next-line to ignore the next line.
                                 Use /* eslint-disable */ to ignore all warnings in a file.
```
`src/main.js`を以下の通り修正。
```javascript:src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import vuetify from './plugins/vuetify'
import { Amplify } from 'aws-amplify'
import AwsExports from './aws-exports'    <- ここの命名をCamelCaseに変更
import {
  applyPolyfills,
  defineCustomElements
} from '@aws-amplify/ui-components/loader'
Amplify.configure(AwsExports)
applyPolyfills().then(() => {
  defineCustomElements(window)
})

Vue.config.productionTip = false

new Vue({
  router,
  store,
  vuetify,
  render: h => h(App)
}).$mount('#app')

```
ついでにGitHubにPushするとAmplifyのデプロイが走るか確認できてラッキーだったね。
GitHubのコミット
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/4c33e21c-28ea-5b8d-ccf0-d3fe04cf040d.png)
Amplifyのコンソール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/08ff8027-2a4b-1d84-426d-06173d8ae31a.png)
無事デプロイできたので、左下のリンクからアプリを開いてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/30c1b80a-681c-52a3-0034-6fe320601419.png)
（葉っぱが見切れてる…）

適当に書いて流してみました。
DynamoDBに登録されるはずです。
（思ってないことを書いています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/1ec297d3-cb0f-4398-4772-bf1c4fa31b48.png)

DynamoDBのテーブルが自動的にできているので、そこを見ると項目ができています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/040e319b-ff55-8657-ad2d-2402042e939a.png)

## 微調整
最後にアプリの挙動を少し調整します。
①流すボタンを押したらテキストボックスをリセットする。
ちょこちょこ修正しました。
```vue:src/views/leaves/Create.vue
<template>
  <v-container>
    <h1>葉っぱを流す</h1>
    <v-img
      max-height="300"
      max-width="300"
      src='../../../public/img/leaf1.png'
      >
      <v-row align-content="center" style="height: 300px">
        <v-col align="center">{{ form.message }}</v-col>
      </v-row>
    </v-img>
    <v-form
        ref="form"
        v-model="valid"
        lazy-validation
        @submit.prevent="submitCreate">
        <v-text-field
          v-model="form.message"
          :counter="300"
          :rules="nameRules"
          label="思うこと…"
          required
          clearable
        ></v-text-field>
        <v-btn
          :disabled="!valid"
          color="success"
          class="mr-4"
          type="submit"
        >
          流す
        </v-btn>
      </v-form>
  </v-container>
</template>

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

export default {
  name: 'LeafCreate',
  data () {
    return {
      form: {
        message: ''
      },
      valid: true,
      nameRules: [
        v => !!v || 'なにか入力してね',
        v => (v && v.length <= 300) || '300文字未満にしてね'
      ]
    }
  },
  methods: {
    async submitCreate () {
      if (this.$refs.form.validate()) {  // 送信ボタンを押したときにValidateしてOKの場合だけ送信する
        await API.graphql({
          query: createLeaf,
          variables: { input: this.form }
        })
          .then((result) => {
            console.log(result)
            this.$router.push({ name: 'LeafCreate' })
            this.form.message = ''  // テキストフィールドにバインドしている変数をリセット
            this.$refs.form.resetValidation()  // Validation状態もリセット
          })
          .catch((error) => {
            console.log(error)
          })
      }
    }
  }
}
</script>

```

②ブラウザ更新したりするとAccessDeniedになる
このように。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/46205ca3-aa4b-9cf9-9ea8-56209e3f9a7c.png)
AmplifyでSPAを使う時に発生してしまうそうです。これを回避する場合はAmplifyに設定を追加します。
参考：https://blog.serverworks.co.jp/tech/2020/03/02/amplify-console-redirect/
Amplifyコンソールの「書き換えて、リダイレクト」を開き、「書き換えを追加して、リダイレクト」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/7b941406-5ccb-db40-0182-6ed155c5a772.png)
下記のように入力します。
* 送信元アドレス：`</^[^.]+$|\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf|map|json)$)([^.]+$)/>`
* ターゲットアドレス：`/`
* 入力：`200`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/412de1ca-061a-6f01-3cfa-2dbf525d60d0.png)

最後に「保存」を押すと設定が保存されます。これでF5を押しても403になりません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57278/4e4c5729-70d1-9677-37ed-d42e1a519527.png)

# 次回
なんとかして川に流す動きを作りたいです