Returning binary data (jpg) from Lambda via API Gateway

In that case, what about configuring binary mode for content types?

Currently my code is working by having specified multipart/form-data in the “Binary media types” through the console.

Fortunately, this survives deploys, but still is far from ideal.

I’ve been delving into the API docs (why aren’t they searchable) to see how this is configured… haven’t found anything yet.

oh, duh–

http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings-configure-with-control-service-api.html#api-gateway-payload-encodings-setup-with-api-set-encodings-map

Hi guys,

I just implemented a test project for returning binary data (PDFs in my case). It even works to request directly from the browser without setting Accept header.

Sample code here:

The only manual change needed is to add to binary Media Types in API Gateway console.

The manual steps described by krisgholson was not needed for me.

4 Likes

Thank you so much for providing this example. I spend a few hours yesterday and was not able to figure it out. What I was missing was “isBase64Encoded” in the response and adding * / * to the binary media type on the API gateway.

Test code for returning a png image from s3

        s3.getObject(params).promise().then((result) => {
            let resp = {
                statusCode: 200,
                headers: {
                    'Content-Type': 'image/png'
                },
                body: result.Body.toString('base64'),
                isBase64Encoded: true
            };
            callback(null, resp);
        });

I have to add image/png to the request header to get a valid png file. If I add * / * then I get a file slight larger and it is no longer a valid png file.

curl -H "Accept:image/png" https://xxxxxxxxx.us-west-1.amazonaws.com/dev/imagetest > test1.png

I had some serious fun trying to get this to work, when there were multiple media types in the header which for me I could not control AWS state it should pick the first one. This does not seem to work when configuring the relevant binaryType in the UI.

If anyone else comes across this and struggles, my solution for now at least was to create a local plugin that sets the CONVERT_TO_BINARY on the Integration Response (means I could not use Lambda Proxy Integration) and re-deploy the API.

Config is set as follows:

Anyway hope this helps some people in my scenario :smiley:

3 Likes

OH, this must find its way into core! PLEASE!

Or, at the very least, could you please publish the plugin separately?

Bit slow on the reply for this one, I would separate this out into its own plugin just not sure it is 100% the correct implementation. Mainly due to the having to wait 1 minute as otherwise AWS moans about API deployment limits.

That said I will try it without the wait and do some testing with Serverless 1.6.1 and see if it is all good. If so will tidy it up and release as a separate plugin.

Cheers,
Jon

1 Like

Hey,

this is a great example for returning binary data from a Lambda, thanks @jonsharratt.

I was wondering if anyone has an example of how to receive a file through API Gateway in a Lambda function. My problem and example is better described here:
https://forums.aws.amazon.com/message.jspa?messageID=771214#771214

TL;DR The API Gateway wierldy stuffs (as a string) all the POST-data (Content-Type, body-file itself, etc.) into the event.body of the Lambda.

Cheers!
-Keksike

Thanks for this @bni

I’ve done this, and covered how in another thread.

Basically, yes, you have to (a) set “multipart/form-data” as a binary type, and (b) parse the multi-part MIME body in your own code.

I have code for this in Python, if that helps.

Hi @funkybob,

Could you share your python in which you managed to return an image through AWS lambda? I would like to perform this action using lambda via api gateway without redirects (returning 200 code).

THanks

@bni
Thanks for the code. I am able to get the object back in binary format. I am able to test this in API Gateway. However the browser fails to load the PDF. I have added additional headers look at other blogs but it did not help. Can someone help?
The additional headers are:
“Expires” : “0”,
“Cache-Control” : “must-revalidate, post-check=0, pre-check=0”,
“Pragma” : “public”,
“Content-Length” : data.size

thanks funkybob, my problem is not add * / * to the binary media type.
just add image/png not work for me. very strange.