AWS の開始方法

フルスタック React アプリケーションを構築する

AWS Amplify を使用してシンプルなウェブアプリケーションを作成する

モジュール 5: ストレージを追加する

このモジュールでは、ストレージと、画像をアプリケーションのメモに関連付ける機能を追加します

概要

メモアプリケーションが機能するようになったので、各メモに画像を関連付ける機能を追加しましょう。このモジュールでは、Amplify CLI とライブラリを使用して、Amazon S3 を利用するストレージサービスを作成します。その後、前のモジュールで作成した GraphQL スキーマを更新して、画像を各メモに関連付けます。最後に、React アプリケーションを更新して、画像のアップロード、フェッチ、レンダリングを有効にします。

実行する内容

このモジュールでは、次のことを行います。
  • ストレージサービスを作成する
  • GraphQL スキーマを更新する
  • React アプリケーションを更新する

主要な概念

ストレージサービス - 画像や動画などのファイルの保存とクエリは、ほとんどのアプリケーションの一般的な要件です。これを行う 1 つのオプションは、ファイルを Base64 エンコードし、文字列として送信してデータベースに保存することです。これには、エンコードされたファイルが元のバイナリよりも大きいこと、オペレーションの計算コストが高額になること、適切なエンコードとデコードの複雑さが増すことなどの欠点があります。もう 1 つのオプションは、ファイルストレージ用に特別に構築および最適化されたストレージサービスを用意することです。Amazon S3 などのストレージサービスは、これを可能な限り簡単、高パフォーマンス、低コストにすることを目指しています。

 所要時間

10 分

 利用するサービス

実装

  • 画像ストレージ機能を追加するために、Amplify ストレージカテゴリを使用します。以下のほとんどのオプションはデフォルトの選択のままにすることができますが、Enter キーを押してプロンプトを続行する前に、作成/更新、読み取り、および削除のオプションでスペースを押して、各オプションを必ず個別に選択してください。

    amplify add storage
    
    ? Select from one of the below mentioned services: Content (Images, audio, video, etc.)
    ? Provide a friendly name for your resource that will be used to label this category in the project: imagestorage
    ? Provide bucket name: <your-unique-bucket-name>
    ? Who should have access: Auth users only
    ? What kind of access do you want for Authenticated users? create/update, read, delete
    ? Do you want to add a Lambda Trigger for your S3 Bucket? (y/N) no
  • 次に、amplify/backend/api/notesapp/schema.graphql を開き、次のスキーマで更新します。

    type Note @model @auth(rules: [ { allow: public } ] ){
      id: ID!
      name: String!
      description: String
      image: String
    }

    必ずファイルを保存してください。

  • ストレージサービスがローカルで設定され、GraphQL スキーマが更新されたので、Amplify push コマンドを実行して更新をデプロイできます。

    amplify push --y
  • バックエンドが更新されたので、React アプリを更新して、メモ用に画像をアップロードおよび表示する機能を追加しましょう。src/App.js を開き、次の変更を加えます。

    a.まず、Storage クラスと Image コンポーネントを Amplify インポートに追加します。

    import { API, Storage } from 'aws-amplify';
    import {
      Button,
      Flex,
      Heading,
      Image,
      Text,
      TextField,
      View,
      withAuthenticator,
    } from '@aws-amplify/ui-react';

    b.メモに関連付けられている画像がある場合は、fetchNotes 関数を更新して画像を取得します。

    async function fetchNotes() {
      const apiData = await API.graphql({ query: listNotes });
      const notesFromAPI = apiData.data.listNotes.items;
      await Promise.all(
        notesFromAPI.map(async (note) => {
          if (note.image) {
            const url = await Storage.get(note.name);
            note.image = url;
          }
          return note;
        })
      );
      setNotes(notesFromAPI);
    }

    c.画像がメモに関連付けられている場合は、createNote 関数を更新して、画像をローカル画像配列に追加します。

    async function createNote(event) {
      event.preventDefault();
      const form = new FormData(event.target);
      const image = form.get("image");
      const data = {
        name: form.get("name"),
        description: form.get("description"),
        image: image.name,
      };
      if (!!data.image) await Storage.put(data.name, image);
      await API.graphql({
        query: createNoteMutation,
        variables: { input: data },
      });
      fetchNotes();
      event.target.reset();
    }
    

    d.メモが削除されたときにストレージからファイルを削除するように deleteNote 関数を更新します。

    async function deleteNote({ id, name }) {
      const newNotes = notes.filter((note) => note.id !== id);
      setNotes(newNotes);
      await Storage.remove(name);
      await API.graphql({
        query: deleteNoteMutation,
        variables: { input: { id } },
      });
    }

    e.return ブロックのフォームにその他の入力を追加します。

    <View
      name="image"
      as="input"
      type="file"
      style={{ alignSelf: "end" }}
    />

    f.メモ配列をマッピングするときに、画像が存在する場合はそれをレンダリングします。

    {notes.map((note) => (
      <Flex
        key={note.id || note.name}
        direction="row"
        justifyContent="center"
        alignItems="center"
      >
        <Text as="strong" fontWeight={700}>
          {note.name}
        </Text>
        <Text as="span">{note.description}</Text>
        {note.image && (
          <Image
            src={note.image}
            alt={`visual aid for ${notes.name}`}
            style={{ width: 400 }}
          />
        )}
        <Button variation="link" onClick={() => deleteNote(note)}>
          Delete note
        </Button>
      </Flex>
    ))}

    g.変更をコミットして GitHub にプッシュします。その後、ビルドが完了するまで待ち、完全にアプリケーションが稼働するのを確認します。

    git add .
    git commit -m "Added graphql and storage"
    git push origin main
  • アプリをテストするには、start コマンドを実行します。

    npm start

    これで、各メモ用の画像をオプションでアップロードできるようになります。

  • 個々のサービスの削除

    個々のサービスを削除するには、Amplify remove コマンドが使えます。

    amplify remove auth
    
    ? Choose the resource you would want to remove: <your-service-name>

    次に、Amplify push コマンドを実行します。

    amplify push

    プロジェクト全体を削除する

    プロジェクトと、関連付けられたリソースを削除するには、Amplify delete コマンドを実行します。

    amplify delete

まとめ

AWS Amplify を使用してウェブアプリケーションをデプロイしました。 アプリケーションに認証を追加して、ユーザーがサインアップ、サインイン、アカウント管理できるようにしました。アプリケーションには、Amazon DynamoDB データベースで設定されたスケーラブルな GraphQL API もあり、ユーザーはメモを作成および削除できます。また、Amazon S3 を利用してファイルストレージを追加し、ユーザーが画像をアップロードしてアプリケーションで表示できるようにしました。

このページはお役に立ちましたか?

お疲れさまでした。

AWS でウェブアプリケーションを構築できました! 次のステップとして、特定の AWS テクノロジーをさらに詳しく見て、アプリケーションを次のレベルに引き上げます。