HaneCa

独り立ちへ向けた長い道

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

投稿日: 2018年5月5日 最終更新日: 2019年1月1日

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でファイルをアップロードするサイトの構築

参考サイト

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください