我正在尝试将谷歌日历 API 部署到 AWS Lambda。由于我在从事件字典(由 lambda 从 POST 请求的 JSON 有效负载中创建)中提取值时遇到问题,因此我创建了一个玩具函数来测试
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"
}
在使用以下 JSON 在 Lambda 控制台上进行测试时,我得到了正确的响应。
测试有效载荷: { "start_time" : "2018-01-24T09:00:00", "end_time" : "2018-01-24T13:00:00", "类型": "创建", "event_identifier": "PVNO", "摘要": "公司", "预订电子邮件": "abc@example.com" }
响应:
{
"body": "create",
"headers": {
"Content-Type": "text/plain"
},
"statusCode": 200
}
当我从邮递员(二进制或正文 POST)(或在 API 网关控制台上测试)发送相同的有效负载时,当我从 event.get("type") 返回值时,我得到"无"。
为了进一步解释,如果我尝试获取 event.get('body') 并将其全部作为字符串返回,我会得到以下内容,根据 lambda 事件的工作方式,这是不正确的:
{
"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"
}
我的问题:
- 我做错了什么?
- 如何从事件字典中获取正确的值?
当您在本地或通过 Lambda 控制台调用 lambda 时,您将直接调用该 lambda,因此您的 lambda 会准确接收您发送的内容。
当您通过 API 网关调用它时,API 网关会根据您的 HTTP 请求为您创建event
对象。它添加了 HTTP 标头、路径、查询字符串、有效负载等。
以下是您从 API 网关调用中获得的event
的摘要:
{
"resource": "Resource path",
"path": "Path parameter",
"httpMethod": "Incoming request's method name"
"headers": {Incoming request headers}
"queryStringParameters": {query string parameters }
"pathParameters": {path parameters}
"stageVariables": {Applicable stage variables}
"requestContext": {Request context, including authorizer-returned key-value pairs}
"body": "A JSON string of the request payload."
"isBase64Encoded": "A boolean flag to indicate if the applicable request payload is Base64-encode"
}
参考: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-simple-proxy-for-lambda-input-format
如您所见,body
将作为string
发送给您,您可以使用json.loads()
进行解析。
- 请求完全打包,并在
event
字典的'body'
键中作为单个字符串发送。 - 此行为不同于测试控制台或从 CLI 调用,后者在
event
字典中只有有效负载,这意味着event.get('type')
直接工作。
演示如何访问有效负载中"type"
键的值的示例代码:
import json
def lambda_handler(event, context):
body_str = event.get("body", "{}")
body_str = body_str if body_str else "{}"
body_obj = json.loads(body_str)
a = body_obj.get("type", "")
我有一个更好的测试建议。
只需返回您在lambda_handler中收到的事件即可。
如前所述,AWS在内部测试Lamda,这导致了一个解决方案:您需要在AWS获得它时使用整个帖子,您不能像使用curl那样仅发送一些数据json。
因此,如有疑问,您可以在 Lambda 接收事件时使用
import json
def lambda_handler(event, context):
return { "statusCode": 200, "body": json.dumps(event, indent=2) }
保存后,此 lambda 将返回您需要粘贴到 AWS Lmbda 页面上的测试事件中的 json。