파일을 S3에 업로드하기

이제 노트에 첨부 파일을 추가해 보겠습니다. 여기서 사용할 흐름은 매우 간단합니다.

  1. 사용자가 업로드할 파일을 선택합니다.
  2. 파일이 사용자 폴더 아래에 S3로 업로드되고, 키를 반환받습니다.
  3. 파일 키를 첨부 파일로 하여 노트를 생성합니다.

AWS Amplify가 제공하는 Storage 모듈을 사용할 것입니다. Cognito Identity Pool 생성 챕터에서 로그인한 사용자가 S3 버킷 내의 폴더에 접근할 수 있도록 허용했던 것을 기억할 것입니다. AWS Amplify는 파일을 _비공개_로 저장하려는 경우 이 폴더에 직접 저장합니다.

또한, 미리 살펴보자면 노트를 생성할 때와 노트를 수정할 때 파일을 업로드할 것입니다. 이를 도와줄 간단한 편의 메서드를 만들어 보겠습니다.

S3에 업로드하기

Change indicator src/lib/awsLib.ts 파일을 생성하고 다음 내용을 추가하세요:

import { Storage } from "aws-amplify";

export async function s3Upload(file: File) {
  const filename = `${Date.now()}-${file.name}`;

  const stored = await Storage.vault.put(filename, file, {
    contentType: file.type,
  });

  return stored.key;
}

위 메서드는 몇 가지 작업을 수행합니다.

  1. 파일 객체를 매개변수로 받습니다.

  2. 현재 타임스탬프(Date.now())를 사용해 고유한 파일 이름을 생성합니다. 물론 앱이 많이 사용된다면 이 방식이 고유한 파일 이름을 만드는 최선의 방법은 아닐 수 있습니다. 하지만 지금은 괜찮습니다.

  3. Storage.vault.put() 메서드를 사용해 파일을 S3의 사용자 폴더에 업로드합니다. 만약 공개적으로 업로드하려면 Storage.put() 메서드를 사용할 수 있습니다.

  4. 저장된 객체의 키를 반환합니다.

노트 생성 전 파일 업로드

이제 업로드 메서드가 준비되었으니, 노트 생성 메서드에서 이를 호출해 보겠습니다.

Change indicator src/containers/NewNote.tsxhandleSubmit 메서드를 다음 코드로 교체하세요.

async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
  event.preventDefault();

  if (file.current && file.current.size > config.MAX_ATTACHMENT_SIZE) {
    alert(
      `파일 크기가 ${
        config.MAX_ATTACHMENT_SIZE / 1000000
      } MB보다 작아야 합니다.`
    );
    return;
  }

  setIsLoading(true);

  try {
    const attachment = file.current
      ? await s3Upload(file.current)
      : undefined;

    await createNote({ content, attachment });
    nav("/");
  } catch (e) {
    onError(e);
    setIsLoading(false);
  }
}

Change indicator 그리고 src/containers/NewNote.tsx의 헤더에 다음 코드를 추가하여 s3Upload를 포함시키세요.

import { s3Upload } from "../lib/awsLib";

handleSubmit에서 변경한 내용은 다음과 같습니다:

  1. s3Upload 메서드를 사용해 파일을 업로드합니다.

  2. 반환된 키를 사용해 노트 객체를 생성할 때 이를 추가합니다.

이제 브라우저로 전환해 파일을 업로드한 후 폼을 제출하면 노트가 성공적으로 생성되고 앱이 홈페이지로 리디렉션되는 것을 확인할 수 있습니다.

다음으로, 사용자가 생성한 노트 목록을 볼 수 있도록 하는 기능을 추가할 예정입니다.