Open abhinav-jain09 opened 4 years ago
Description
Lambda configure with SAM to read JSON from request body does not work
Briefly describe the bug you are facing.
Steps to reproduce
I tried to develop a simple API where the request is in the form of simple JSON
"{\"test\": \"hello world\"}"
I wrote a sam template as follows
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > sam-app Sample SAM Template for sam-app # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 20 Resources: HelloWorldFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: HelloWorldFunction Handler: helloworld.App::handleRequest Runtime: java8 MemorySize: 512 Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object Variables: PARAM1: VALUE Events: HelloWorld: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /{proxy+} Method: POST RestApiId: !Ref HelloWorldApi RequestModel: Model: RequestClass # REQUIRED; must match the name of a model defined in the Models property of the AWS::Serverless::API Required: true # OPTIONAL; boolean HelloWorldApi: Name: HelloWorldFunctionApiGateway Type: AWS::Serverless::Api Properties: StageName : dev Models: RequestClass : { "$schema": "http://json-schema.org/draft-04/schema#", "title": "RequestClass", "type": "object", "properties": { "test": { "type": "string" }} } Outputs: # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function # Find out more about other implicit resources you can reference within SAM # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api HelloWorldApi: Description: "API Gateway endpoint URL for Prod stage for Hello World function" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" HelloWorldFunction: Description: "Hello World Lambda Function ARN" Value: !GetAtt HelloWorldFunction.Arn HelloWorldFunctionIamRole: Description: "Implicit IAM Role created for Hello World function" Value: !GetAtt HelloWorldFunctionRole.Arn
then I used the event.json as
sam local invoke HelloWorldFunction --event events/event.json
{ "body": "{\"test\": \"hello world\"}", "resource": "/{proxy+}", "path": "/hello", "httpMethod": "post", "isBase64Encoded": false, "queryStringParameters": { "foo": "bar" }, "pathParameters": { "proxy": "/path/to/resource" }, "stageVariables": { "baz": "qux" }, "headers": { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "en-US,en;q=0.8", "Cache-Control": "max-age=0", "CloudFront-Forwarded-Proto": "https", "CloudFront-Is-Desktop-Viewer": "true", "CloudFront-Is-Mobile-Viewer": "false", "CloudFront-Is-SmartTV-Viewer": "false", "CloudFront-Is-Tablet-Viewer": "false", "CloudFront-Viewer-Country": "US", "Host": "1234567890.execute-api.us-east-1.amazonaws.com", "Upgrade-Insecure-Requests": "1", "User-Agent": "Custom User Agent String", "Via": "1.1 08f323deadbeefa7af34d5feb414ce27.cloudfront.net (CloudFront)", "X-Amz-Cf-Id": "cDehVQoZnx43VYQb9j2-nvCh-9z396Uhbp027Y2JvkCPNLmGJHqlaA==", "X-Forwarded-For": "127.0.0.1, 127.0.0.2", "X-Forwarded-Port": "443", "X-Forwarded-Proto": "https" }, "requestContext": { "accountId": "123456789012", "resourceId": "123456", "stage": "prod", "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", "requestTime": "09/Apr/2015:12:34:56 +0000", "requestTimeEpoch": 1428582896000, "identity": { "cognitoIdentityPoolId": null, "accountId": null, "cognitoIdentityId": null, "caller": null, "accessKey": null, "sourceIp": "127.0.0.1", "cognitoAuthenticationType": null, "cognitoAuthenticationProvider": null, "userArn": null, "userAgent": "Custom User Agent String", "user": null }, "path": "/prod/path/to/resource", "resourcePath": "/{proxy+}", "httpMethod": "POST", "apiId": "1234567890", "protocol": "HTTP/1.1" } }
Handler is as follows
package helloworld; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; /** * Handler for requests to Lambda function. */ public class App implements RequestHandler<RequestClass,Object> { public Object handleRequest(RequestClass input, Context context) { Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "application/json"); headers.put("X-Custom-Header", "application/json"); **Output of the follwoing line always null** System.out.println(input.getTest()); try { final String pageContents = this.getPageContents("https://checkip.amazonaws.com"); String output = String.format(input.toString(), pageContents); return new GatewayResponse(output, headers, 200); } catch (IOException e) { return new GatewayResponse("{}", headers, 500); } } private String getPageContents(String address) throws IOException{ URL url = new URL(address); try(BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) { return br.lines().collect(Collectors.joining(System.lineSeparator())); } } }
Request class is follows
package helloworld; public class RequestClass { public String test; public String getTest() { return test; } public void setTest(String test) { this.test = test; } @Override public String toString() { return "HelloWorld{" + "test='" + test + '\'' + '}'; } public RequestClass() { } }
Observed result
The value of system out should be "Test" but its printing "null" meaning the RequestClass is not mapped with the incoming JSON.
This is supported in AWS lambda as follows
https://docs.aws.amazon.com/lambda/latest/dg/java-handler-io-type-pojo.html
Please provide command output with
--debug
flag set.Expected result
Should be able to map JSON to the java POJO object
Describe what you expected.
Additional environment details (Ex: Windows, Mac, Amazon Linux etc)
OS:MAC OS
sam --version
:SAM CLI, version 0.22.0
Add --debug flag to command you are running
Description
Lambda configure with SAM to read JSON from request body does not work
Briefly describe the bug you are facing.
Steps to reproduce
I tried to develop a simple API where the request is in the form of simple JSON
"{\"test\": \"hello world\"}"
I wrote a sam template as follows
then I used the event.json as
sam local invoke HelloWorldFunction --event events/event.json
Handler is as follows
Request class is follows
Observed result
The value of system out should be "Test" but its printing "null" meaning the RequestClass is not mapped with the incoming JSON. This is supported in AWS lambda as follows https://docs.aws.amazon.com/lambda/latest/dg/java-handler-io-type-pojo.html
Please provide command output with
--debug
flag set.Expected result
Should be able to map JSON to the java POJO object
Describe what you expected.
Additional environment details (Ex: Windows, Mac, Amazon Linux etc)
sam --version
:SAM CLI, version 0.22.0Add --debug flag to command you are running