AWS 入門

建置完整堆疊的 React 應用程式

使用 AWS Amplify 建立簡單的 Web 應用程式

單元 5:新增儲存體

在本單元中,您將新增儲存體至應用程式,並讓影像能夠與應用程式中的筆記關聯

概觀

現在,記事應用程式開始工作了,讓我們新增將影像與每個筆記關聯的功能。在本單元中,您將使用 Amplify CLI 和程式庫來建立使用 Amazon S3 的儲存服務。然後,您將更新在上一個單元中建立的 GraphQL 結構描述,以將影像與每個筆記關聯。最後,您將更新 React 應用程式以實現影像上傳擷取和呈現。

您會完成的目標

在本單元中,您將會學習以下內容:
  • 建立儲存服務
  • 更新 GraphQL 結構描述
  • 更新 React 應用

主要概念

儲存服務 – 儲存和查詢影像和影片之類的檔案是大多數應用程式的常見要求。一種選擇是對檔案進行 Base64 編碼,並作為字串傳送以儲存在資料庫中。舉例來說,這樣做的缺點是,編碼檔案比原始二進位檔案大,操作在運算上成本高昂,並且由於需要正確編碼和解碼,所以複雜性有所增加。另一種選擇是專門為檔案儲存建立和優化儲存服務。諸如 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.首先,將儲存類別和影像元件新增至 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 陣列上進行映射時,如果存在影像則呈現:

    {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 部署了一個 Web 應用程式! 您已將身份驗證新增到應用程式中,從而允許使用者註冊、登入和管理其帳戶。該應用程式還具有可擴展的 GraphQL API 以及 Amazon DynamoDB 資料庫,允許使用者建立和刪除筆記。您還使用 Amazon S3 新增了檔案儲存體,以便使用者上傳影像並在應用程式中進行檢視。

本頁對您是否有幫助?

恭喜您!

您已成功在 AWS 上建立 Web 應用程式! 下一步,您將深入了解特定的 AWS 技術,並將您的應用程式提升到一個新的水平。