Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get object from S3 in AWS Lambda function and send to Api Gateway

I am trying to get a .jpg file from a bucket and send it back to api gateway. I believe I have the setup correct as I see stuff being logged. It grabs the file from s3 fine, and gm is the graphicsmagick library. Not sure if I am using it right though.

In the lambda function I do this (alot of the code comes from the aws example):

async.waterfall([
    function download(next) {
        console.log(srcKey);
        console.log(srcBucket);
        // Download the image from S3 into a buffer.
        s3.getObject({
                Bucket: srcBucket,
                Key: srcKey
            },
            next);
        },
    function transform(response, next) {
        console.log(response);
        next(null, 'image/jpeg', gm(response.Body).quality(85));

    },

    function sendData(contentType, data, next){
        console.log(contentType);
        console.log(data);
        imageBuffer = data.sourceBuffer;
        context.succeed(imageBuffer);
    }
    ]
);

The response header has content-length: 85948, which doesn't seem right because the original file is only 36kb. Anyone know what I'm doing wrong?

like image 570
cmk Avatar asked Aug 25 '15 20:08

cmk


1 Answers

You can achieve Get Image <-> API Gateway <-> Lambda <-> S3 integration with ease.

In lambda, instead of json, return base64 string representation of image (buffer.toString('base64')), force API Gateway to convert the string to binary and add specific Content-Type (so you don't need to use their limited binary support that enforce you to send a specific Accept header).

In AWS console, go to API Gateway, then go to the relevant method and update the settings:

  • Integration Request

    • Uncheck: Use Lambda Proxy integration
  • Method response

    • Add Response -> HTTP Status: 200
    • Add Header: Content-Type
  • Integration Response -> Header Mapping -> Response header -> Content-Type

    • Mapping value: 'image/jpeg' (single quote matter)

From command line, run the command below to force convert string to binary. First, retrieve the rest-api-id and the resource-id from API Gateway. Then, run in CLI (replace rest-api-id and resource-id with your own):

aws apigateway put-integration-response --rest-api-id <rest-api-id> --resource-id <resource-id> --http-method GET --status-code 200 --content-handling CONVERT_TO_BINARY
like image 128
lenaten Avatar answered Oct 11 '22 00:10

lenaten