I am working with a simple AWS Lambda function :
public class CreateOrderLambda {
private final ObjectMapper objectMapper = new ObjectMapper();
// This Particular Order needs to be saved to the DynamoDB.
private final DynamoDB dynamoDB = new DynamoDB(AmazonDynamoDBClientBuilder.defaultClient());
public APIGatewayProxyResponseEvent createOrder(final APIGatewayProxyRequestEvent input,
final Context context)
throws JsonProcessingException {
Order thisOrder = objectMapper.readValue(input.getBody(), Order.class);
Now, Here is how the template looks like :-
CreateOrdersFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabspw/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: ordersapi
Handler: com.aditya.learn.function.CreateOrderLambda::createOrder
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref OrdersTable
Events:
OrderEvents:
Type: Api
Properties:
Path: /orders
Method: POST
While I hit the aforesaid API through API Gateway, I am able to execute the request well :-
curl --location --request POST 'https://o2cf5ti7ik.execute-api.us-east-1.amazonaws.com/Prod/orders/' \
--header 'Content-Type: application/json' \
--data-raw '{
"id":1001,
"itemName":"Nariyal",
"quantity":3
}'
But, while testing the Lambda standalone from console with following request :
{
"id": 1004,
"itemName": "HoneyAlmondFlakes",
"quantity": 7
}
It gives following error :-
START RequestId: 63aa8edd-38b3-408e-8727-652393964f14 Version: $LATEST
argument "content" is null: java.lang.IllegalArgumentException
java.lang.IllegalArgumentException: argument "content" is null
at com.fasterxml.jackson.databind.ObjectMapper._assertNotNull(ObjectMapper.java:4757)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3515)
at com.aditya.learn.function.CreateOrderLambda.createOrder(CreateOrderLambda.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
END RequestId: 63aa8edd-38b3-408e-8727-652393964f14
REPORT RequestId: 63aa8edd-38b3-408e-8727-652393964f14 Duration: 4.72 ms Billed Duration: 5 ms Memory Size: 512 MB Max Memory Used: 134 MB
Basically, it's not able to typecast the request into the custom object.
Is the API0Gateway passing the request to Lambda in some special way ? What am I missing in testing the Lambda standalone ?
Any help shall be highly appreciated.
Basis of Marcin's response :-
Tried with following structure of event :-
{
"resource": "/",
"path": "/",
"httpMethod": "POST",
"requestContext": {
"id":7,
"itemName":"Flakes",
"quantity":6,
"resourcePath": "/",
"httpMethod": "POST",
"path": "/Prod/",
"requestId": "JKJaXmPLvHcESHA=",
"time": "23/Jan/2021:05:16:23 +0000"
},
"headers": {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"accept-encoding": "gzip, deflate, br",
"Host": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36",
"X-Amzn-Trace-Id": "Root=1-5e66d96f-7491f09xmpl79d18acf3d050"
},
"multiValueHeaders": {
"accept": [
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
],
"accept-encoding": [
"gzip, deflate, br"
]
},
"isBase64Encoded": false
}
Still same error :-
START RequestId: 028d4942-f2cf-4dbc-afe3-08783a106555 Version: $LATEST
argument "content" is null: java.lang.IllegalArgumentException
java.lang.IllegalArgumentException: argument "content" is null
at com.fasterxml.jackson.databind.ObjectMapper._assertNotNull(ObjectMapper.java:4757)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3515)
at com.aditya.learn.function.CreateOrderLambda.createOrder(CreateOrderLambda.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
END RequestId: 028d4942-f2cf-4dbc-afe3-08783a106555
REPORT RequestId: 028d4942-f2cf-4dbc-afe3-08783a106555 Duration: 371.97 ms Billed Duration: 372 ms Memory Size: 512 MB Max Memory Used: 134 MB Init Duration: 2568.48 ms
Lambda standalone from console
The event
that you get in your lambda function from API, and the one used when you run the function from the console are different. The event
from api passed to your function will have a fixed known format. But when you run the function from console, you are passing the event
in the incorrect format, thus it all breaks.
You have to ensure that your event
structure used when you run the code in console matches the event
structure from the API format.