I am trying to deploy a google calendar api to AWS Lambda. Since I was facing a problem in extracting the value from the event dictionary (created by lambda from the JSON payload of a POST request), i created a toy function to test
def handler(event,context):
a=event.get("type")
if a=='create':
return {
"statusCode": 200,
"headers": { "Content-Type": "text/plain"},
#"body": "Event_id"+ str(event_identifier) + " Event Link: " +str(links)
"body" : str(a)
}
else:
return {
"statusCode": 200,
"headers": { "Content-Type": "text/plain"},
#"body": "Event_id"+ str(event_identifier) + " Event Link: " +str(links)
"body" : "nope"
}
While testing on the Lambda console with the following JSON, I get the correct response.
Test Payload: { "start_time" : "2018-01-24T09:00:00", "end_time" : "2018-01-24T13:00:00", "type": "create", "event_identifier": "pvno", "summary": "Company", "booking-email": "abc@example.com" }
Response:
{
"body": "create",
"headers": {
"Content-Type": "text/plain"
},
"statusCode": 200
}
When I send the same payload from postman(binary or body POST) (or test on API gateway console), I get "None" when I return the value from event.get("type").
To explain further, if I try and get the event.get('body') and return it all as a string I get the below, which is incorrect according to how the lambda event should work:
{
"start_time" : "2018-01-24T09:00:00",
"end_time" : "2018-01-24T13:00:00",
"type": "create",
"event_identifier": "pvnoc",
"summary": "Company",
"booking-email": "abc@example.com"
}
My questions:
- What am I doing wrong?
- How can I get the correct value from the event dictionary?
As said AWS tests Lamda internally, which leads to a solution: you need to use the whole post as AWS get it, you cannot just send some data json as you do with curl.
So, if in doubt, you can fetch the event as Lambda receive it using
Once saved, this lambda will return the json you'll need to paste into the testing event on AWS Lmbda page.
After a whole day spent trying to figure this out, realised the following:
The solution I found is the following (assuming you want to access the value of "type" key in payload) , though hoping for a cleaner solution:
Hope this helps someone!
I have a better suggestion to test.
Just return the event that you are receiving in the lambda_handler.
When you invoke the lambda locally or through the Lambda console, you are invoking that lambda directly and so your lambda receives exactly what you're sending.
When you invoke it through API Gateway, API Gateway creates the
event
object for you based on your HTTP request. It adds the HTTP headers, path, query strings, payload, etc.Here's a summary of what you're getting as an
event
from an API Gateway invocation:Reference: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-simple-proxy-for-lambda-input-format
As you can see, the
body
will be sent to you as astring
which you can parse usingjson.loads()
.