前回、前々回でLambda + API GatewayでREST API、CSVのダウンロード、CORSの対応を紹介してきました。 今回は画像や動画、ZIPファイル等のバイナリファイルをダウンロードする方法を紹介します。
前回、前々回のLambdaを使いまわしますので、先にそちらを参照してください。
全体的な流れは次のようになります
図を見ていただくと分かりますが、今回はAPI Gatewayを少し変更します。
画像ファイルの用意
今回はS3 へ画像ファイルを用意しました。
この画像をAPI Gateway、Lambdaを経由してダウンロードさせたいと思います。
Lambdaの用意
Lambdaを次のように変更してください
var AWS = require('aws-sdk'); var s3 = new AWS.S3(); exports.handler = async (event) => { var data = await getS3Object(); return data.Body.toString('base64'); }; const getS3Object = () => { return new Promise((resolve) => { var params = { Bucket: "<S3のバケット名>", Key: "<S3のフォルダ>/xpcloud_icon.png" }; s3.getObject(params, function(err, data) { resolve(data); }); }); };
この行でS3から取得するためにAWS SDKを読み込んでいます。 Lambdaではデフォルトでライブラリがインストールされているため"require"と書くだけで使用することができます。 さらにLambdaに割り当てたロールで実行されるためACCESS_KEY等の認証情報も不要です。
getS3Object
このメソッドでS3からファイルを取得しています。 今回はファイル名を決め打ちで記載しましたが、event変数の中にURLパラメータが入っているので、ファイル名を動的にすることも可能です。
return data.Body.toString('base64');
この行で画像ファイルを文字列へ変換してLambdaを終了しています。
API Gatewayの用意
統合リクエストを開きます。
前回作成したAPI Gatewayのままだと"Lambdaプロキシ統合の使用"にチェックが入っていると思いますので、外します。 これを外すことで上の図の右下"統合レスポンス"を変更することができるようになります。
"メソッドの実行"を押して戻り、次はメソッドレスポンスを変更します。
HTTP200のレスポンスに設定を足します。 200のレスポンスヘッダーに"Content-Type"(大文字小文字もしっかり)、 200のレスポンス本文に"image/png"/"Empty"を設定します。 "Empty"という名前が紛らわしいですが、オブジェクトをそのまま渡すというモデルになってます。
このあたりの設定値の意味は全部設定した後で説明します。 "メソッドの実行"で戻り、次は統合レスポンスを開きます。
メソッドレスポンスのステータス200の項目が最初からあると思いますので、開いて編集します。 コンテンツの処理を"バイナリに変換"、 Content-Type(上で設定した物です)のマッピングの値に「'*'」(シングルクォート、アスタリスク、シングルクォートの3文字)を設定して保存します。
メソッドの実行で戻ると、このような設定になっていると思います。
アクション>APIのデプロイ を選択します。
ステージはすでに作成されているはずなので、それを選べばOKです。 デプロイを押すとAPI Gatewayの設定が反映されます。
ではURLを開いてみましょう。 前回作成したURLと同じです。
画像が表示されれば成功です。 もしどこかで設定を間違い、修正しても画像が上手く表示されない場合は、何度かF5でリロードしてみてください。 キャッシュが残っていて表示されない場合があります。
色々設定しましたが、全体的な流れを解説します。
あとがき
Content-Typeを変更するとMP3やMP4にも対応できるため、WEBで使う機能は一通り網羅できたと思います。 Lambdaを通しているため認証をからめたり複雑な処理も可能です。