Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS API Gateway and Lambda to return image

Tags:

Say I have this HTML:

<img src="http://example.com/pic"/>

What I would like to do is have example.com/pic map to an AWS API Gateway endpoint.

That endpoint would then call a lambda function.

That lambda function would read a random image from an s3 bucket and return it.

So my aim is to use a STANDARD HTML image tag and end up with an image from an s3 bucket but going via some decision code in the lambda to decide the image to return.

I know you can use s3 to serve static content directly (hence the lambda to make the decision about what image). I also know I could do stuff in the lambda like b64 encode the response and then handle it on the client but I am aiming to use the standard HTML IMG tag.

Is this possible?

I've tried using the ResponseStreamHandler (Java SDK) for the lambda and returning the byte array of the image and also added the API gateway config to not map the output to JSON, but nothing seems to work!

like image 559
user1736191 Avatar asked Mar 04 '16 19:03

user1736191


People also ask

How do I return an image in Lambda?

To return binary media from an AWS Lambda proxy integration, base64 encode the response from your Lambda function. You must also configure your API's binary media types. To use a web browser to invoke an API with this example integration, set your API's binary media types to */* .

Can a Lambda function return a file?

You can't do that. Your file handle only has meaning in the context of your lambda function, it means nothing outside of it.


1 Answers

It seems AWS has simplified this process, so that many answers are outdated and/or overly complicated.

This is how I got Lambda to return an image through the API Gateway, as of June 2018:

1) In API Gateway, enable Use Lambda Proxy integration for your API. (This setting is located on the Integration Request section, where you had set the type to Lambda.)

2) In API Gateway, select your API and click Settings. In Binary Media Types add */*. (Note: I tried adding simply 'image/jpeg', but it seems to require */* to get all of this to work)

3) Be sure to deploy your API, otherwise your changes will not be live. (In API Gateway, select your API, then Actions > Deploy API).

4) In your Lambda code, return your image in Base64 encoding (this example is C# code):

    // set the Content-type header
    // set to whichever image type you're returning
    var headersDic = new Dictionary<string, string>();
    headersDic.Add("Content-type", "image/jpeg");

    // return the response object that APIGateway requires
    return new APIGatewayProxyResponse
    {
        StatusCode = 200,
        Headers = headersDic,
        // return the image in Base64 encoding
        Body = Convert.ToBase64String(...your image data...),
        IsBase64Encoded = true
    };

Done.

If you've setup your API to not require authentication, simply type your API link into your browser, and it will display the image. Or put the API link into an IMG tag. e.g. <img src="https://asdf.execute-api.us-east-1.amazonaws.com/live/myapi" />

Note: Even though in step 2 you set the Binary Media Types to */*, API Gateway will still return text if that is what your Lambda is returning.

like image 128
Doug S Avatar answered Nov 13 '22 01:11

Doug S