Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change method naming of AwsProxyRequest for Jackson and other serializers. #262

Closed
MarvGilb opened this issue Jun 14, 2019 · 16 comments
Closed
Labels
Milestone

Comments

@MarvGilb
Copy link

MarvGilb commented Jun 14, 2019

Serializer like Jackson's ObjectMapper are using method names for serialization and deserialization.
Prefixes like get/set/is will be removed and the following String will be used as parameter names.

For the property isBase64Encoded the method names are:

  • isBase64Encoded
  • setIsBase64Encoded

See: https://github.com/awslabs/aws-serverless-java-container/blob/e4f4d4de6016a60d3fe728181d24aa4d91e645ec/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/model/AwsProxyRequest.java#L171

This leads to a serialization of
{ "base64Encoded" }
which can not be deserialized because the expected value name is: isBase64Encoded

Please rename the getter to getIsBase64Encoded or isIsBase64Encoded, so that the property is serialized as:
{ "isBase64Encoded" }

@Marclev78
Copy link

Marclev78 commented Jun 18, 2019

This should be treated as a high priority as it is causing requests to sam local start-api to consistently fail with an InternalServerError when trying to deserialise the response.

@sapessi
Copy link
Collaborator

sapessi commented Jun 18, 2019

Thanks for the feedback @Marclev78 - I'll work to replicate and push a fix with the next patch release. Hoping to get it out this week.

@sapessi sapessi added the bug label Jun 18, 2019
@sapessi sapessi added this to the Release 1.3.1 milestone Jun 18, 2019
@sapessi
Copy link
Collaborator

sapessi commented Jun 20, 2019

Hey @Marclev78, I have a fix for this about to go out in the core branch. However, I doubt this is the cause of your issue. Requests are only de-serialized, which happens correctly, the framework never serializes them. Still, I have added the annotation on the field like we do in the response to make sure this happens correctly.

Can you share a stack trace of what is happening with SAM local so that we can figure out what the root cause of the issue is?

sapessi added a commit that referenced this issue Jun 20, 2019
@sapessi
Copy link
Collaborator

sapessi commented Jun 27, 2019

Release 1.3.2 - which includes this fix - is on its way to maven central! Resolving this issue.

@gakinson
Copy link

I am experiencing this issue using the latest 1.3.2 version.

@sapessi
Copy link
Collaborator

sapessi commented Sep 27, 2019

Hi @gakinson, the annotation is definitely there in the latest release (code).

I suspect your issue may be caused by the fact that you are using the typed handler rather than the stream one: The typed handler (receives a proxy event + context and returns a proxy response) uses Lambda's built-in serialization mechanism which does not read/use annotations. I would recommend switching to the stream handler (see the examples). The stream handler uses the object mapper included in this framework which will respect the annotations.

@gakinson
Copy link

Hello @sapessi ,

Thanks for the prompt response. I can switch to use that to test, but I also just created a new instance of a jackson ObjectMapper which should respect annotations, I think, but it still does not do the deserialization correctly.

Thank you,
Geoffrey K

@gakinson
Copy link

Here is my post from thread aws/aws-sam-cli#1193 :

Hello, here are my notes on how I could get it working by duplicating your class and playing around with annotations.

Failed attempts

  1. Move the @JsonProperty annotation to the field and removing it from the "is" getter
  2. Tried add additional letters tot he prefix

Successful attempts

  1. Deleting the "isBase64Encoded()" and putting JsonProperty("isBase64Encoded") to the field isBase64Encoded
  • Issue with this is that there is no getter now.
  1. Rename the "isBase64Encoded()" function to "getIsBase64Encoded()"

Still trying some others that are backwards compatible, but please address this in some way.

@gakinson
Copy link

@sapessi

I have tried this using RequestStreamHandler and it all works. I read a little more regarding RequestHandler and I see now.

Thanks for your patience.

@sapessi
Copy link
Collaborator

sapessi commented Sep 27, 2019

Great! Apologies for missing your earlier messages @gakinson

@sapessi
Copy link
Collaborator

sapessi commented Sep 27, 2019

When you use a typed handler (RequestHandler<AwsProxyRequest, AwsProxyResponse>) the event and output are marshalled/unmarshalled by AWS Lambda, it is outside of Serverless Java Container's control. The Lambda Java runtime is configured to ignore annotations altogether. That's why it doesn't pick them up no matter what.

@kastork
Copy link

kastork commented Sep 27, 2020

What's odd is, when running sam local you get the base64Encoded field, but when deploying to lambda/api-gatway you get isBase64Encoded.

This is using 1.3.2 and the typed handler.

@sapessi
Copy link
Collaborator

sapessi commented Sep 29, 2020

Which Lambda runtime are you using @kastork? java8, java8.al2, or java11?

@kastork
Copy link

kastork commented Sep 30, 2020

@sapessi I'm using java11

@kastork
Copy link

kastork commented Sep 30, 2020

@sapessi Because of your question, I tried it with java8 and java8.al2. The results are the same locally.

@kristofvb
Copy link

@sapessi This really is a problem with class AwsProxyResponse. The getter/setter pair should really be getIsBase64Encoded/setIsBase64Encoded. As you said the Lambda Java runtime will not take into account the added Jackson annotation. The correct lambda response format is documented here.

Also, as can be seen in the linked issue for SAM CLI, this tool is totally unforgiving in handling responses with the wrong property base64Encoded.

Would you be willing to provide both properties base64Encoded and isBase64Encoded in the response (by having two pairs of getter/setter methods)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants