LoginSignup
16
16

More than 5 years have passed since last update.

API Gateway+Lambdaでバイナリデータを処理

Last updated at Posted at 2018-07-05

1. まとめ

クライアントからAPI GatewayにPOSTされたバイナリデータをLambdaで何かしらの処理を実施する方法を記載する.ここでは,実例としてバイナリデータとして画像ファイルを受け取り,Lambdaにて画像をS3に保存する方法を記載する.

2. 目次

  • 1 まとめ
  • 2 目次
  • 3 簡易処理フロー
  • 4 実装
    • 4.1 Lambda
    • 4.2 API Gateway
  • 5 テスト
  • 6 参考リンク

3. 簡易処理フロー

  • API Gateway
    • バイナリメディアタイプにてimage/*を設定しバイナリを扱えるよう設定
  • Lambda
    • Base64にエンコードされたデータをデコードし画像ファイルのバイナリーデータを取得
    • 画像をS3に保存
  • S3
    • 画像を格納

4. 実装

 
下記のcURLで叩いて,S3に画像が保存されていればOK

$ curl -X POST -H 'Content-type: image/jpeg' --data-binary "@ramen.jpeg" https://xxxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/upload

ramen.jpg

4.1. Lambda

コード全体

'use strict';

const aws = require('aws-sdk');
const s3 = new aws.S3({ apiVersion: '2006-03-01'});

exports.handler = (event, context, callback) => {

    // add logging level
    console.log = console.log.bind(null, '[LOG]');
    console.info = console.info.bind(null, '[INFO]');
    console.warn = console.warn.bind(null, '[WARN]');
    console.error = console.error.bind(null, '[ERROR]');

    // variables
    var response = {}

    // check event
    console.log(event)

    // if data is encoded with base64, then decode with base64 and save it in S3
    if (event.isBase64Encoded === true) {

        // decode
        var decode = new Buffer(event.body,'base64');

        // save data in s3
        var params = {
                        Bucket: 's3-xxxxxxxxxxxxxxx-20180702', 
                        Key: 'ramen.jpg', 
                        ContentType: 'image/jpeg', 
                        Body: decode
                    };
        s3.putObject(params, function(err, data) {
            if (err) {
                console.error(err);
                console.error('image upload failed');

                // create response
                response.statusCode = 400
                response.body = JSON.stringify({
                    message: 'fail.'
                })
                callback(null, response);

            } else {
                console.log('image upload success');

                // create response
                response.statusCode = 200
                response.body = JSON.stringify({
                    message: 'image has been uploaded to S3'
                })
                callback(null, response);
            }
        });

    } else {

        // create response
        response.statusCode = 400
        response.body = JSON.stringify({
            message: 'fail.'
        })
        callback(null, response);
    }
};

補足

eventの中身の確認

下記でCloudWatchにログとして書き出す

    // check event
    console.log(event)

下記が結果.重要な部分だけ抽出.
event.bodyがbase64でencodeされた画像データ
event.isBase64Encodedがtrueになっておりbase64でバイナリデータをエンコードされているのがわかる

body: '/9j/4AAQSkZJRgABAQAASABIAAD/99b06vJCFQ+N .. 省略 ... h/9k=',
isBase64Encoded: true 

デコード

base64でエンコードされていることを確認し,デコードnew Buffer(event.body,'base64')を実施

    // if data is encoded with base64, then decode with base64 and save it in S3
    if (event.isBase64Encoded === true) {
        // decode
        var decode = new Buffer(event.body,'base64');

4.2. API Gateway

バイナリメディアタイプを設定しない場合のレスポンス

$ curl -X POST -H 'Content-type: image/jpeg' --data-binary "@ramen.jpg" https://xxxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/upload

{"message":"fail"}

バイナリメディアタイプにimage/*を追加し変更を保存.ステージに反映するには再度APIをデプロイする必要がある.
binary_media_type.jpg

バイナリメディアタイプを設定した場合のレスポンス

image/*が登録されているため,image/jpegが通る.

$ curl -X POST -H 'Content-type: image/jpeg' --data-binary "@ramen.jpg" https://xxxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/upload

{"message":"image has been uploaded to S3"}

適当にimage/*以外にContent-typeを設定してみると,エラーになる.想定通りの挙動

$ curl -X POST -H 'Content-type: text/plain' --data-binary "@ramen.jpg" https://xxxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/upload

{"message":"fail"}

Content-typeを外してみてもエラーになる.想定通りの挙動

$ curl -X POST --data-binary "@ramen.jpg" https://xxxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/upload

{"message":"fail"}

5. テスト

cURLで叩いてみる

$ curl -X POST -H 'Content-type: image/jpeg' --data-binary "@ramen.jpg" https://xxxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/v1/upload

{"message":"image has been uploaded to S3"}

S3に保存されていることを確認

S3_upload.png

6. 参考リンク

なし

16
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
16