AWS Lambda Base64 Encoded Request Body/Response Body
Table of Contents
In some case, the request body in lambda is base64 encoded string with isBase64Encoded flag. Most guides teach developer to decode the request body in lambda function. This post will discuss the root cause of this problem.
Some guides advice user set */*
in binary media type in API gateway for handling all media type without warning including AWS documention. In API Gateway, the binary media types setting not only related to converting base64 string to binary in response. This setting also related to converting request body to base64 string.
Example repo
You can clone example repo and deploy to your AWS account to test the lambda function.
- POST /input API logging the JSON stringified event object in CloudWatch Log, sending JSON or form-data but set the Content-Type request header to
application/octet-stream
orimage/jpeg
manually to see the base64 encoded request body. Sending JSON or form-data request without change Content-Type header to see normal request body. - GET /image API setting the Accept request header to
image/jpeg
to see the decoded image or*/*
to see the base64 encoded string.
Encoded request body
Encoded request body depends on two factors, binary media type in API gateway setting and Content-Type request header.
I have added
application/octet-stream
and image/jpeg
type in binary media type in API gateway.
If the Content-Type request header is application/octet-stream
or image/jpeg
, the request body will be encoded.
Otherwise, the request body is same as the request body from client.
Beware that common design of API server accepting json request body or form-data. If application/json
or application/x-www-form-urlencoded
type is added in binary media type in API gateway, the json request body or form-data will be encoded to base64 string even client is not sending file.
For the wildcard case like application/*
in API gateway binary media type setting, API gateway will match the Content-Type request header start from application/
.
So using application/*
in binary media type setting will convert the request body with Content-Type header application/x-www-form-urlencoded
, application/json
, application/pdf
, etc. to base64 string.
Using */*
in API gateway binary media type setting means encoding any request body to base64 string since */*
can match any Content-Type. So using */*
in binary media type setting is highly not recommended.
PS. Missing Content-Type header in request look like API gateway will assume the request is JSON format and will use application/json
for matching
Encoded response body
Converting base64 string to binary in response depends on two factors, binary media type in API gateway setting and Accept request header in client.
I have added
application/octet-stream
and image/jpeg
type in binary media type in API gateway.
If the first vaule of Accept request header is application/octet-stream
or image/jpeg
and the lambda payload contain isBase64Encoded true flag, the response body will be converted from base64 string to binary before returning to client.
For the wildcard case like application/*
in API gateway binary media type setting, API gateway will match the Accept response header start from application/
.
So using application/*
in binary media type setting will convert base64 encoded response body to binary when Accept request header is set to application/json
, application/pdf
, etc. (Wildcard in API gateway setting)
But if we explicitly set type in API gateway binary media type setting like application/octet-stream
but set Accept request header to wildcard application/*
, the base64 string will not convert back to binary before sending out to client. (Wildcard in Accept request header)
When Accept request header accept multiple media type, API gateway only consider the first media type in header.
It means adding application/octet-stream
in binary media type in API gateway but set Accept request header to application/*, application/octet-stream
, the response body will keep in base64 string and not converting back to binary.