API Gateway経由でS3にReactでファイルアップロード(概要)

S3にファイルをアップロード機能をサーバレスで実現しようと思い、API Gatewayを使えば楽にできるだろうと思っていたらかなりハマりました。おそらく、他にも方法はあるでしょうが、今回は次のような方法で解決することができました。

やりたいこと

今回、やりたいことは、Reactで実装されたUIからAPI Gatewayを経由してHTTP POSTでファイルをアップロードした際に、S3の適切な場所にファイルをアップロードできるようにすることです。

サービス構成と処理手順

今回はこのような構成と手順でサービスを構築しました。

  1. ユーザはブラウザでReactで構築されたサイトにアクセスする。
  2. Reactで構築されたサイトのフォームからファイルをアップロードする。
  3. Reactでbase64変換してHTTP POSTでAPI Gatwayに送る。
  4. API GatewayにつながったLambdaにPOSTされたデータを渡す。
  5. Lambdaでbase64からバイナリに変換する。
  6. S3の適切なバケットへファイルがPUTする。
実現手順
  1. Reactでファイルをアップロードする機能を実装する
  2. IAMで適切なアクセス権を持つユーザ、ロールを作成する
  3. S3でファイルをアップロードするバケットを作成する
  4. AWS Lambdaでファイルを受け取ってS3にアップロードする機能を実装する
  5. API GatewayとLambda関数を関連付けて公開する

かなりボリュームが多くなったため、これらそれぞれを別々の投稿としました。ここでは、これを実現する上ではまったポイントだけを書こうと思います。

はまったポイント

axiosでファイルをPOSTするときに、POSTするパラメータを格納するために、FormDataオブジェクトを利用したことが原因でエラーが発生していました。これが、Content-Type ErrorやBodyの形式が問題があるなど、正確なエラーメッセージを返してくれればもう少し早く解決したのでしょうが、今回は、「No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://xxxxx’ is therefore not allowed access. The response had HTTP status code 400.」と、クロスドメインのエラーとして返されたため、数日はまることになってしまいました。

最終的には、FormDataを利用せず、Base64変換してJSONのvalueに代入してPOSTすることで、今回は解決させました。

しかし、他のサイトを見てみると、バイナリのままPOSTしたり、さらにはLambdaを介さなくて、直接、API GatewayからS3へPUTする方法も書かれていたので、他にもよりスマートな解決方法がありそうです。

関連ページ
  • Reactでファイルをアップロードするサイトの構築
参考サイト
スポンサーリンク
スポンサーサイト
スポンサーサイト

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
スポンサーサイト