构建全栈 React 应用程序

使用 AWS Amplify 创建简易 Android 应用程序

模块 5:添加存储

在本模块中,您将添加存储功能,并实现将图像与应用中的笔记关联

概述

现在,我们的笔记应用已经可以运行了,接下来,我们添加将图像与每条笔记关联的功能。在本模块中,您将使用 Amplify CLI 和 Amplify 库基于 Amazon S3 创建一个存储服务。然后,您将更新在上一个模块中创建的 GraphQL 模式,将图像与每个笔记关联起来。最后,您需要更新 React 应用,以支持图像的上传、下载与显示。

学习目标

在本模块中,您将:
  • 创建存储服务
  • 更新 GraphQL 模式
  • 更新 React 应用程序

关键概念

存储服务:存储和查询图像和视频等文件是大多数应用程序的常见要求。其中一种实现方法是对文件进行 Base64 编码,然后以字符串形式存储在数据库中。这种方法有一些缺点,例如编码后的文件比原始二进制文件更大、操作的计算开销大,以及增加了正确编码和解码的复杂性。另一种选择是使用专门为文件存储而构建和优化的存储服务。Amazon S3 这样的存储服务就是为了使这一过程尽可能简便、高效、成本低。

 时长

10 分钟

 使用的服务

操作步骤

  • 要添加图像存储功能,我们将使用 Amplify Storage(存储)类别:对于下面的大多数选项,您可以保留默认选择,但请确保分别选择 create/update、read 和 delete 选项,方法是在按 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 类和 lmage 组件通过 import 从 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. 在返回块的表单中添加一个额外的输入:

    <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 部署了一个 Web 应用程序!您已为应用添加了身份验证功能,允许用户注册、登录并管理他们的账户。该应用还配置了一个可扩展的 GraphQL API,使用 Amazon DynamoDB 数据库,允许用户创建和删除笔记。您还使用 Amazon S3 添加了文件存储功能,以便用户可以上传图像并在应用程序中查看。

恭喜您!

您在 AWS 上成功构建了一个 Web 应用程序!下一步,您可以深入学习特定的 AWS 技术,将您的应用程序提升到新的水平。