This tutorial shows how to configure API Gateway using Claudia API Builder to send or receive binary files.
Prerequisites
- Claudia 2.6.0 or later
- Claudia API Builder 2.4.0 or later
Basics of binary handling with API Gateway
Since November 2016, API Gateway has basic support for binary transfers. It can transform incoming binary files into base64 encoded strings before passing on to a Lambda function, and transform base64 encoded Lambda resutls into binary files.
Incoming request are transformed into base64 strings if:
- The request content type matches one of the pre-configured binary content types, and
- The request content handling is not set to
'CONVERT_TO_BINARY'
Results are transformed into binary content from base64 if:
- The result content type matches one of the pre-configured binary content types, and
- The
'Accept'
header on the request matches one of the pre-configured binary content types, and - The response content handling is set to
'CONVERT_TO_BINARY'
.
Lambda integration quirks
Although the API Gateway documentation suggests otherwise, it seems that for Lambda integrations, setting the incoming request content handling to 'CONVERT_TO_TEXT'
is not necessary, as any matching binary type is automatically encoded into base64 for AWS Lambda integrations. You can set it to 'CONVERT_TO_BINARY'
to prevent the transformation.
Similarly, although the documentation suggests that multiple content types can be specified in the Accept
header for binary responses, it seems that this breaks the conversion. This makes the current implementation useless for browsers, which by default request complex Accept
headers. This means that it’s currently not possible to use the API Gateway/AWS_PROXY integration to return images that can be just included into a web page using the img
tag.
How Claudia API Builder helps
Claudia API Builder makes it easier to handle binary content by doing several things automatically for you:
- It sets some common content types to be treated as binary by default, including various image content types,
application/pdf
andapplication/octet-stream
. - It will automatically decode incoming base64-encoded bodies into a
Buffer
object (so you can directly save it to a file, for example). - It will automatically encode
Buffer
results into base64. (so you can directly return the result offs.readFile
from an API endpoint handler). - It allows you to easily set incoming request and response content handling.
### Configuring an API
- Use
api.setBinaryMediaTypes(array)
to configure MIME types your API wants to treat as binary. By default, common image types,application/pdf
andapplication/octet-stream
are treated as binary. If you plan to use one of those types, you do not need to callsetBinaryMediaTypes
. - Use
requestContentHandling
in the handler configuration to set the required incoming binary content handling behaviour (API Gateway Integration content handling). Valid values are'CONVERT_TO_BINARY'
(prevents encoding) and'CONVERT_TO_TEXT'
(applies base64 encoding to incoming requests). - Use success.contentHandling in the handler configuration to set the required response content handling behaviour (API Gateway Integration Response content handling). Valid values are
'CONVERT_TO_BINARY'
(transform from base64 to binary content) and'CONVERT_TO_TEXT'
(do not transform the result, return it as base64 string). Remember to set thesuccess.contentType
to the appropriate binary content type as well.
## Responding with binary content
To respond with binary content, make sure to set the response success.contentHandling
to 'CONVERT_TO_BINARY'
, and return a content type matching the configured binary types. Claudia API Builder will automatically convert a binary buffer to a base64 string. Here is how you can serve a binary file to API clients – Note that we’re directly using the results of fs.readFile
(a Promise
version), which provides a buffer.
To retrieve this file, you must set the Accept
header to image/png
:
Requesting with binary content
You can also use the binary support to process incoming binary files. Claudia API Builder will populate request.body
with a binary buffer automatically in case of base64 encoded binary content.
For example, we can use the ImageMagick identify
tool to get basic information about image files. This example will save the incoming file, execute identify
, clean up, and return the result. Note that we’re directly using fs.writeFile
(a Promise
version) to save the request body into a temporary file, because it is a binary buffer. No specific API endpoint configuration is needed here.
To use this service, make sure to include the Content-Type
header into your request.
Using binary content for both request and response
We can combine both techniques to create a service for thumbnails. The endpoint will receive an image, resize it, and return the result. In this case, we’ll need to configure the response content handling. Note that we can directly store request body into a file (Claudia API builder will process and convert the incoming body into a binary buffer), and that we can directly return the results of a binary file read (Claudia API Builder will convert it into a base64 string).
To use this service, you’ll have to set both the request content type and the accepted response content type:
To see this in action, check out the Binary Content Handling example project.