2

When writing a function for AWS Lambda (in Java/Scala), the handler function can have one of different signatures:

// Raw input / output
def handleRequest(is: InputStream): OutputStream = ???

// Using the AWS dependency
def handleRequest(input: APIGatewayProxyRequestEvent, context: Context): APIGatewayProxyResponseEvent = ???

This is the two possible signatures I know of, at least. Maybe there is more.

The difference is that the first one is a raw response, that needs to be packed into a REST response by the API Gateway with manually configured properties like media type and response code.

The second response seems to utilize the Lambda Proxy Integration and will extract all configuration from the APIGatewayProxyResponse.

Now for my question:

The field body of APIGatewayProxyResponse is of type String. To me it looks like this POJO is serialized to JSON before being sent to the API Gateway. This would make it impossible to serve binary data like images or PDF files.

The raw OutputStream cannot carry the information about headers etc. (or can it?), which means I cannot serve multiple different media types.

Of course I could convert images, for example, to Base64. But that is far from optimal.

Is there a way I can serve different (binary and non-binary) media types (with correct headers etc.) in a single AWS Lambda handler? How do I have to configure the API Gateway for that?

4
  • You can user output stream to send send full response (including header) as json. JSONObject response = new JSONObject(); response.put("headers", headerJsonObject); response.put("body", responseBody.toString());OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8"); Commented Jan 29, 2019 at 16:20
  • @Kaushal okay, but I'm pretty sure I won't be allowed to just write binary garbage into the JSON. Commented Jan 29, 2019 at 16:22
  • For binary, don't send json response. Depending on case either send json or binary in output stream. API gateway api can handle response based on what it is configured for. Example docs.aws.amazon.com/apigateway/latest/developerguide/… Commented Jan 29, 2019 at 16:24
  • @Kaushal my question is concerning a single handler that can do both. Commented Jan 29, 2019 at 16:41

1 Answer 1

1

Note: This answer is based on reading the docs. I haven't tried it in practice so it may not work.

If you open the "Output Format of a Lambda Function for Proxy Integration" section of the documentation you may see isBase64Encoded field and following text:

The output body is marshalled to the frontend as the method response payload. If body is a binary blob, you can encode it as a Base64-encoded string and set isBase64Encoded to true. Otherwise, you can set it to false or leave it unspecified.

And if you open APIGatewayProxyResponse in the .Net library you can see the IsBase64Encoded property there. It looks like it is just Java API that does not expose this field. But all the rest of the infrastructure should support it. You may also see that a similar field was added to APIGatewayProxyRequestEvent.java at some point but not to APIGatewayProxyResponse. So I think a following workaround should work: create your own APIGatewayProxyResponseEvent class with isBase64Encoded field and use it. Or just extend from the standard com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent and add this field in your subclass. I expect that if you match the naming convention, it should work. It should be marshalled to a JSON after all.

Sign up to request clarification or add additional context in comments.

7 Comments

@MarkusAppel, reading the doc I would expect that if you set isBase64Encoded = true and the binaryMediaTypes is configured, the proxy would decode the base64 and deliver it to the client as raw data. I haven't tried it though. See also Support Binary Payloads in API Gateway
that sounds reasonable. Too bad you still have to base64 - encode, it would be so much better without.
@MarkusAppel, I would suggest that you mark this as an accepted answer only after you try it and ensure it works in practice. As of now it is only an educated guess.
Your answer already helped a lot, and could be altered according to new findings. I unmarked it anyways.
@MarkusAppel, SO is an answering platform and a knowledge base at the same time and sometimes those features are at odds. If it works, come back and mark it as an accepted answer so people know it works. If it doesn't, come back and leave a comment that it still doesn't work.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.