Reputation: 41
I have an iOS app that calls a AWS Lambda function. I would like the Lambda function to get some files from a server and send it back to the iOS app, through the Lambda proxy feature.
I am directly invoking the Lambda function from my app using the generated SDK. I couldn't find a documentation explaining how to exchange data other than JSON encoded requests.
How should I go about this?
Upvotes: 4
Views: 10061
Reputation: 2195
A simple implementation base on limitation of Lambda and Api Gateway, and also the extra bytes which you need to reserve for headers around > .5mb
const someFile = fs.readFileSync('somefile.mp4') // simulate 4mb file
module.exports.res = async event => {
return {
statusCode: 200,
headers: {
// all the other headers needed for file download
Content-Type: 'video/mp4'
},
// must use Buffer.from if not
// API Gateway will report failed binary transformation
body: Buffer.from(someFile ).toString('base64'),
isBase64Encoded: true
}
}
Upvotes: 0
Reputation: 179364
Lambda's only interface to the outside world is JSON.
To return text data from Lambda, you have to return it as a string, and deserialize the string from the JSON response.
To return binary data from Lambda, the data must be first transformed (encoded) using an encoding that cannot ever produce a series of bytes that is not also a valid sequence of UTF-8 characters, because JSON cannot serialize non-character data (and not every possible combination of bytes corresponds to a valid character or characters). The common strategy for doing this is to use base-64 encoding. Base-64 losslessly converts a series of bytes (octets) into a different series of bytes that are also always valid 7 bit ASCII characters, using an 8:6 conversion ratio (coding 6 bits per byte). You would then need to decode this data back from base-64 to binary.
You can do this decoding of JSON and base-64 on the client, but there are also a couple of other options, if you don't like that idea.
Both API Gateway and CloudFront's Lambda@Edge feature provide a built-in conversion capability to convert the base-64 payload (from the JSON Lambda response) back to binary, if you don't want to do it on the client.
API Gateway supports all Lambda runtimes, and expects this format...
"isBase64Encoded": true,
"body": "the-base-64-encoded-body",
Lambda@Edge supports only Node.js Lambda functions, but is less expensive than API Gateway. It expects a base-64 response to include...
"body": "the-base-64-encoded-body",
"bodyEncoding": "base64",
The viability of either approach depends on your security needs. API Gateway supports authentication via IAM as well as other mechanisms. CloudFront + Lambda@Edge doesn't support IAM auth but can be used with CloudFront signed URLs or Cognito or other custom authorization mechanisms.
If the "files" you mentioned are coming from a server, API Gateway can also proxy these files directly from the server, without a Lambda function handling the content (though depending on your security needs, a Lambda Custom Authorizer might be desirable, to authenticate the request but then simply tell API Gateway to allow the request to be forwarded to the backend).
Or, if the files are objects from S3, then you can access S3 directly, similiar to the way you are accessing Lambda, now.
Upvotes: 7