s3 버킷 이미지 해결 폴링

곤란한 일



s3에 업로드한 이미지의 URL을 참조했을 때, lamda 함수(리사이즈를 실시한다)의 처리가 따라잡지 않고 미해결로 403이 돌아온다.
(온메모리 미리보기 이미지에서 요구 사항을 충족할 수 없는 경우)

전제



s3에 업로드한 이미지에 대해 리사이즈 등의 lamda 함수를 실행하여 최적화된 이미지를 생성하고 전용 버킷에 재등록하는 처리를 하고 있는 경우에 발생하는 사례.



해결책



fetch API로 이미지의 URL을 두드려 statusCode: 200이 돌아올 때까지 Polling한다.
import axios from 'axios'
import * as api from '@/api'

type Form = {
  Content-Type: string
  Policy: string
  X-Amz-Algorithm: string
  X-Amz-Credential: string
  X-Amz-Date: string
  X-Amz-Signature: string
  key: string
  x-amz-server-side-encryption: string
}

const checkS3Resolve = async (url: string) => {
  const res = await fetch(url)
  // 成功したら200を返す
  return res.status
}

export const upload = async (
  host_url: string,
  url: string,
  file: File,
  form: Form,
) => {
  const formData = new FormData()
  for (const key in form) {
    const value = form[key]
    if (value !== undefined) {
      formData.append(key, value)
    }
  }
  // fileは最後にappendしないとエラー
  formData.append('file', file)
  await axios.post(url, formData, { timeout: 10000 })

  const hostUrl = `https://s3-ap-northeast-1.amazonaws.com/hoge/origin`

  const delay = (ms: number) => new Promise(res => setTimeout(res, ms))
  let result = 404
  // S3で画像が処理されるまで待つ
  while (result !== 200) {
    // 1.5秒ごとにS3側の状態確認処理を実施
    await delay(1500)
    result = await checkS3Resolve(hostUrl)
  }
  ...
}


마지막으로



꽤 엣지 케이스는 됩니다만, 개인적으로 조금 막혔으므로 기재했습니다.
그 밖에도 좋은 방법 등 있으시면 코멘트 기다리고 있습니다.

AWS 주위의 아키텍처에 대해서는 화상원 데이터는 s3에 격납해, 리사이즈의 처리에 대해서는 lamda를 직접 두드려 버리는 것이 좋다고 하는 코멘트를 받았습니다.
(그쪽이 에러 핸들링 등도 생각하면 좋을 것 같다)
또, 소규모의 안건이라면 화상의 관리는 Firebase Resize Images로 실시하는 것이 간단하다는 소리도 받았습니다.

공부하겠습니다🙏

좋은 웹페이지 즐겨찾기