SANDFISH FACTORY

技術ブログです。python・vuejsを愛でる日々について綴ります

Vue.jsとAWS Amplifyで開発するサーバレスなWebアプリ:storage

はじめに

前回の投稿でAWS Amplifyのauthコンポーネントを用いた認証をアプリに組み込みました。
今回はAWS Amplifyのstorageを少し掘り下げます。 storageを利用できればS3を用いたファイルの保存・参照を簡単に組み込むことができます。

storageコンポーネント

authと同様、aws-amplify-vueにはいくつかのstorageコンポーネントが用意されています。

amplify-photo-picker

概要

amplify-photo-pickerは写真のアップロードに関する機能が用意されています。
このコンポーネントを呼び出すだけローカルファイルを選択し、S3のバケットにアップロードできます。

<template>
<v-container fluid fill-height>
  <v-layout align-center justify-center>
    <div v-if="signedIn">
      <amplify-photo-picker :photo-picker-config="photoPickerConfig" />
      <amplify-s3-album path="upload/"></amplify-s3-album>
      <amplify-sign-out />
    </div>
    <div v-else>
      <amplify-sign-out />
    </div>
  </v-layout>
</v-container>
</template>

<script>
import { AmplifyEventBus } from 'aws-amplify-vue'
import Auth from '@aws-amplify/auth'

export default {
  props: [],
  data () {
    return {
      signedIn: false,
      photoPickerConfig: {
        header: 'Upload Profile Pic',
        accept: 'image/*',
        path: 'upload/'
      }
    }
  },
  async beforeCreate () {
    try {
      await Auth.currentAuthenticatedUser()
      this.signedIn = true
    } catch (err) {
      this.signedIn = false
      console.log(err)
    }
    AmplifyEventBus.$on('fileUpload', (img) => {
      console.log('img:' + JSON.stringify(img))
    })
  }
}
</script>

photoPickerConfigがコンポーネントの設定情報です。

  • header:コンポーネントのヘッダー名
  • title:アップロードボタンの名称
  • accept:送信するファイルのHTMLの許可設定。image/*の場合はimageしか送付できません。
  • path:S3のバケットにアップロードする際のフォルダパス

f:id:sandfish03:20191005104427p:plain
amplify-photo-picker、amplify-s3-albumの利用イメージ

詳しいドキュメントはこちらを参照してください。

イベント

authコンポーネントと同様、発生するイベントはAmplifyEventBus経由で受け取ります。 リスナーを登録して適宜必要な処理を実装します。

AmplifyEventBus.$emit('fileUpload', img) はファイルのアップロードに成功したときに発生します。

今回のサンプルプログラムで実装したのはbeforeCreateフック内でアップロードしたファイルの情報をコンソールに出力しています。
あまり情報は持っておらず、アップロード先のファイルパスだけ取得できるようです。

img:"upload/evi003.jpeg"

出力した結果は上の通りです。uploadフォルダにアップロードするようにしていたため、上記のパスになっています。

import { AmplifyEventBus } from 'aws-amplify-vue'
import Auth from '@aws-amplify/auth'

export default {
  props: [],
  data () {
    return {
      signedIn: false,
  // 〜 省略 〜
  },
  async beforeCreate () {
    try {
      await Auth.currentAuthenticatedUser()
      this.signedIn = true
    } catch (err) {
      this.signedIn = false
      console.log(err)
    }
    AmplifyEventBus.$on('fileUpload', (img) => {
      console.log('img:' + JSON.stringify(img))
    })
  }
}

amplify-s3-album

概要

amplify-s3-album はパラメータで渡したpath配下のファイルを表示する機能が用意されています。
実際にはamplify-s3-image を内部で複数表示する仕組みになっています。 ここAWS AmplifyのAPIを呼び出してファイルパスの一覧を取得しています。

this.$Amplify.Storage.list(this.path, this.options)
        .then(res => {
          that.items = res.map(item => {
            return { path: item.key };
          });
        })
        .catch(e => this.setError(e));

イベント

amplify-s3-albumのイベントはありません。

storageコンポーネントを利用する際の注意点

S3へのアクセスが時間切れで表示されなくなる

コンポーネント内部の処理では毎回、S3 Presigned URL(v4)が発行されて該当のファイルを表示しています。
これの課題はExpireする時間が定められているので、画面を操作せずに一定時間が立って画像を表示しようとすると画像が表示されないことです。
リロードされれば、再度S3 Presigned URL(v4)が発行されて画像が表示されます。
表示されるURLはS3Imageコンポーネント内で設定されており、この中でPresigned URLが発行されています。詳しくはここを参照してください。

this.$Amplify.Storage
        .get(this.imagePath, this.options)
        .then((url) => {
          this.url = url
          })
        .catch(e => this.setError(e));

削除機能のコンポーネントがない

アップしたら削除できないです。AWSマネジメントコンソールでS3の画面から削除するか、AWS AmpifyのAPIを用いて削除処理を個別に実装するしかないです。

いくつか不足している機能もありますが、画像ファイルをS3にアップロードし、確認できました。

まとめ

storageのコンポーネントではあまりカスタマイズが出来ませんが、ほんの数行記載するだけでS3のバケットを利用した画像イメージを管理する仕組みが実現出来ました。
利用シーンは限定的かもしれませんが、この行数で素早くできるのは良いなと思います。

次回はコンポーネントではなく、AWS AmplifyのAPIについて試したいと思います。