How to configure binary support in API Gateway — the easy and working way!

Image for post
Image for post

In this tutorial we are going to enable binary support in API Gateway using AWS console. This task may not sound too complicated yet looking at number of related questions on Stack Overflow [1] [2] [3] and comments like:

I’ve been struggling to do the same for days, but couldn’t find any documentation to back up that it’s possible

it’s not that easy and the process is confusing.

Moreover, in this tutorial we are not going to use CONVERT_TO_BINARY. It’s not necessary. We are going to use as little changes as possible to get binary media types to work.

First we are going to create a lambda function and then we are going to go through step by step API Gateway configuration in order to get an image returned correctly.

Lambda Function

Let’s start by creating a lambda function that returns an image.

We open AWS Console and go to Lambda:

AWS Console — Lambda
AWS Console — Lambda

Next we click on [ Create function ] button:

Create Function
Create Function

On the next screen we use default: Author from scratch option and put function name. In this example we’ll call our lambda image-lambda — name isn’t important and we can choose any:

Create Function — Basic Information
Create Function — Basic Information

Now, let’s click on [ Create Function ] button.

After a few seconds our lambda function will be created:

Lambda successfully created
Lambda successfully created

Let’s scroll down to see inline editor:

Lambda Inline Editor
Lambda Inline Editor

Remove existing code and replace it with:

exports.handler = async (event) => {
const base64Image = "iVBORw0KGgoAAAANSUhEUgAAAKAAAACgCAAAAACupDjxAAAFPklEQVR42u2ZvWsqTRSH7//0g0UEYQmIIIIEBAtBEAIWFhaBgBCwsBBuEQtBEEHSWKSwCFhYSJoUKQIXLgRsLERSCBYSJFgsct7CndmP2RGi7np5OdtlTtw8mY/nnDn+on/8+cWADMiADMiADMiADMiADMiADMiADMiADMiADMiADMiADMiADMiADMiADMiADMiADMiA/0vAm6tMrliu1hoPncdBv9tq3FVKuXTSTC1pmzaT2WK11mj1Br12s35bKeWzydQnWdmYmc6X7xrtbrfdrFUKaTNWIJoY8atssVp/6PQ6rXq1mDFjudMBU9A8f2hjBAbeaBEwmifqqaPXpwN+NPMBHGa59U30Uksrf/G2vaHd433BMxovtaZEn+27jHvUKDzMz7IHN5NrL0V6aInYvOIO3M3kh2a3cjQzkr++G8t/yehszndIrEHchZFZu2NDF597fCfQ25Z7eBqzl3x+3lP87iL86w21ZeDF+5H9YNf3pvp+EVbn1syzxEjsfNObE5Gxd2cAAG79LxrYJ+nsHpR7SlHDm4j89gwvASD55f/tIQDUQxD1IiaOpOUPid12tXWPvqqrLnZEfBlGJvktJmqiqEhERu7RGoBqgPmVqT4X4KfwYYV0U5h3ja0MwFCP6toAjM9wcnFNTJTyZ99F5NUZawXP1ABALaRi4a/AaCqhoh0pOhMYBxJr9SXXqqfOV82I/JVQcsBEsL+7d2xHfcUbgEJo5ZZ04cAf2YlkWBaOiQHmJlhWo9AAt6aNkd0F2g0APvY/NwD01TcsDSBphVewtgIOg82etCP7zLEwgNSWAiXYCbGiPmCavmCfERHdA3gKKDqSgLEKEZCqWtN8JezIPRHNDCATsJJjOx4e4JveNA+izvvUH4WSs0nDujRda02zNCT7FEBup3546jFlOIADrWnsQg+IrSpBCds+2qOQATcJrWlmgr2skfEm/kPHHHUvbmpN45wgTUE6CKivzw8o50k1zR+H70azf3/mmOM6C2WtaWTJAPzRGOCewgec6E0jQ2XdneEjAkArrTWNLBnSVnAaLlIEgE5SU00zDKz9909HufaFBbiOaU0jSwZV01YSSFmRANK93jR97cVqDKAXUX/wQ28aGSoEXOZiq4gAHZ0oprnTmXr2k9v6yYAjnWlmjqrLahqeRga4vdKY5haaFtMmAZQoMkCnoTVQdqBc/qo/DY8jBJS1n9c0FcBYVDy1v/3kjnLM8YDOWr76LvZNp8tQ83YeehQl4HuQacpAfOWccWPhPtyxdaSAlFNN8w6g7S4ZGu4+Up2iBXxSTXMDmF9EtMvK2t+VhqcRA34n/KZ5A/DoLRke7DSc0lSwYQI67cyBk17sXoIsGezu1lhzhwoXcA6vaV4ADP0lQ1esfdqKHFB2VW3T5IFry99lML/t/Nen6AFfPKaZeJax5V7/JhBfXwBwl3GZZpfzVFgy06Qs2iSOdsxpgPTo+npk5CuwRJcBQ3o63jEnAq7j0jRW1ldfybora+WOd8yJgM40DZ6VG6XsMjROcMypgFM5TRnfN52eLsPxjjkVkEquL6fn+lifLgU4diAaWgud4JiTAa2khFjq650GXQyQOgKipcaegyrrqAFXtpDNgFW0UgcaSVEBintw/4DIXy4KuLdJchsU25gAkN5dFJDyCP7KRl5OH+mygEMAWY2IVzEg/nVhwK154EbeONEx5wCk7oFSYGHG5xcHpOWBU/C9ocsDhvswIAMyIAMyIAMyIAMyIAMyIAMyIAMyIAMyIAMyIAMyIAMyIAMy4D/6/AdhR419vDNESgAAAABJRU5ErkJggg==";
const image = Buffer.from(base64Image, 'base64');return image.toString('base64');
};

This piece of code returns an image (Wikipedia logo) encoded as base64 string.

Let’s just save this lambda by clicking on [ Save ] button.

Lambda — Save
Lambda — Save

Just in case, let’s test our Lambda function by using default event and clicking on [ Test ] button. The result will be:

Image for post
Image for post

Lambda part is done.

API Gateway

Now let’s click on Services and choose API Gateway:

Services > API Gateway
Services > API Gateway

We are going to choose [ Create API ]:

Create API
Create API

We use default settings and give a name to our API. In our example, we used image-api:

API settings
API settings

By clicking on [ Create API ] our API will be created.

Now we can choose [ Actions ] and click on Create Method context menu option:

API Gateway — Create Method
API Gateway — Create Method

We select GET and confirm it:

API Gateway — GET
API Gateway — GET

Next, we put our lambda function name in Lambda Function input field, in our case it’s image-lambda and click on [ Save ] button:

GET — setup
GET — setup

We just need to confirm permissions:

Add Permission to Lambda Function
Add Permission to Lambda Function

Finally, we will get to Method Execution screen:

Method Execution
Method Execution

We can deploy our API now to see what it’s returning now. To do that we choose [ Actions ] and Deploy API from the context menu:

Deploy API
Deploy API

We just need to create a new stage, in our example we use sandbox as stage name:

Deploy API — create stage
Deploy API — create stage

Once the deployment is completed we will get an URL for our API:

Invoke URL
Invoke URL

We can use either POSTMAN or web browser to see what’s returned by the URL:

Lambda response in web browser
Lambda response in web browser

Right now, we still can’t view the image. That’s fine.

Let’s go back to Method Execution screen and choose Integration Request by clicking on its header:

Image for post
Image for post

Next, we’ll scroll down to Mapping Templates section and expand it:

Image for post
Image for post

In Content-Type we’ll type image/png and click on confirm tick box icon.

We’ll get a warning about passthrough behaviour:

Image for post
Image for post

However, we can say No, use current settings.

Now, let’s got to our API settings:

API — Resources
API — Resources

On Settings screen, at the bottom, we can add Binary Media Type. Let’s do that by typing image/png and clicking on [ Save Changes ] button.

Image for post
Image for post

Now, we can go back to API Resources:

API Settings
API Settings

Let’s deploy API again:

Image for post
Image for post

Finally, we’ll switch to POSTMAN to see if all is working fine…

POSTMAN — base64 result
POSTMAN — base64 result

…and it isn’t!

However, that’s all actually working correctly as when we enabled binary support there was a message saying:

API Gateway will look at the Content-Type and Accept HTTP headers to decide how to handle the body.

Therefore, we just need to add Accept: image/png and Content-Type: image/png headers in POSTMAN and…

Image for post
Image for post

Success!!! Image is returned correctly.

Conclusion

Our main goal has been achieved — API Gateway returned binary image from lambda and displayed it correctly.

Moreover, in contrast to many outdated tutorials and blog posts, we didn’t actually use Content Type Conversion (CONVERT_TO_BINARY).

Our image wasn’t corrupted with UTF-8 conversion (EF BF BD characters) and we didn’t need to use any functions like $util.base64Decode.

Written by

Programming, project management and politics

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store