Introducción a AWS

Crear una aplicación React de pila completa

Crear una aplicación web simple con AWS Amplify

Módulo 5: agregar almacenamiento

En este módulo, agregará almacenamiento y la capacidad de asociar una imagen con las notas en su aplicación

Información general

Ahora que tenemos una aplicación de notas en funcionamiento, agreguemos la capacidad de asociar una imagen a cada nota. En este módulo, usará la CLI y las bibliotecas de Amplify para crear un servicio de almacenamiento con Amazon S3. Luego, actualizará el esquema GraphQL que creó en el módulo anterior para asociar una imagen a cada nota. Por último, actualizaremos la aplicación React para permitir la carga, la búsqueda y la recuperación de imágenes.

Qué logrará

En este módulo, podrá:
  • Crear un servicio de almacenamiento
  • Actualizar un esquema de GraphQL
  • Actualizar su aplicación React

Conceptos clave

Servicio de almacenamiento: el almacenamiento y la consulta de archivos, como imágenes y videos es un requisito común para la mayoría de las aplicaciones. Una opción para hacer esto es codificar el archivo con Base64 y enviarlo como cadena para guardarle en la base de datos. Esto viene con desventajas, como que el archivo codificado es más grande que el archivo binario original, la operación es costosa en términos informáticos y la codificación y decodificación adecuadas agregan complejidad. Otra opción es crear y optimizar un servicio de almacenamiento específicamente para el almacenamiento de archivos. Los servicios de almacenamiento como Amazon S3 existen para aportar la mayor facilidad, eficiencia y rentabilidad posible.

 Tiempo de realización

10 minutos

 Servicios utilizados

Implementación

  • Para agregar la funcionalidad de almacenamiento de imágenes, usaremos la categoría de almacenamiento Amplify. Puede mantener las selecciones predeterminadas para la mayoría de las opciones siguientes, pero asegúrese de seleccionar las opciones de creación/actualización, lectura y eliminación de forma individual pulsando la barra espaciadora de cada una de ellas antes de pulsar Enter (Entrar) para continuar con el mensaje.

    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
  • Luego, abra amplify/backend/api/notesapp/schema.graphql y actualícelo con el siguiente esquema:

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

    Asegúrese de guardar el archivo.

  • Ahora que se ha configurado el servicio de almacenamiento en forma local y que hemos actualizado el esquema GraphQL, podemos implementar las actualizaciones ejecutando el comando de envío de Amplify:

    amplify push --y
  • Ahora que se ha actualizado el backend, actualicemos la aplicación React para agregar la funcionalidad para cargar y ver imágenes por una nota. Abra src/App.js y realice los siguientes cambios.

    a. Primero agregue la clase de almacenamiento y el componente de imagen a sus importaciones de Amplify:

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

    b. Actualice la función fetchNotes para buscar una imagen si hay una imagen asociada con una nota:

    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. Actualice la función createNote para agregar la imagen a la matriz de imagen local si se asocia una imagen con la nota:

    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. Actualice la función deleteNote para eliminar los archivos del almacenamiento cuando se eliminen las notas:

    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. Agregue una entrada adicional al formulario en el bloque de retorno:

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

    f. Cuando se asigna por la matriz de notas, se obtiene una imagen si existe:

    {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. Confirme sus cambios e introdúzcalos en GitHub. ¡Luego espere a que se complete la compilación para ver su aplicación completa en vivo!

    git add .
    git commit -m "Added graphql and storage"
    git push origin main
  • Para probar la aplicación, ejecute el comando de inicio:

    npm start

    Ahora debería tener la opción de cargar una imagen para cada nota.

  • Eliminación de servicios individuales

    Para eliminar servicios individuales, puede usar el comando de eliminación de Amplify:

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

    Luego, ejecute el comando de envío de Amplify:

    amplify push

    Eliminación de todo el proyecto

    Para eliminar el proyecto y los recursos asociados, puede ejecutar el comando de eliminación de Amplify:

    amplify delete

Conclusión

Ha implementado una aplicación Web con AWS Amplify. Ha agregado autenticación a su aplicación, lo que permite que los usuarios se registren, inicien sesión y administren su cuenta. La aplicación también cuenta con una API GraphQL escalable configurada con una base de datos Amazon DynamoDB que permite que los usuarios creen y eliminen notas. También ha agregado almacenamiento de archivos mediante Amazon S3 para que los usuarios puedan cargar imágenes y las vean en su aplicación.

¿Le resultó útil esta página?

¡Felicitaciones!

¡Creó con éxito una aplicación Web en AWS! Como paso siguiente, profundice aún más en las tecnologías específicas de AWS y lleve su aplicación al siguiente nivel.