我有这个python lambda函数
import json
def lambda_handler(event, context):
post_user = ""
post_user = event["user"]
print(post_user)
return {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": True
}
当我在lambda IDE中运行测试时,这可以按预期工作。测试配置为通过:
{“ user”:“ JOHN”,“ pwd”:“ pwd1”}
但是当我使用API网关运行测试时,出现此错误:
2019年3月25日星期一20:47:29 UTC:端点响应正文 转换:{“ errorMessage”:“'用户'”,“ errorType”:“ KeyError”, “ stackTrace”:[“文件\” / var / task / lambda_function.py \“,第6行,在 lambda_handler \ n post_user = event [\“ user \”] \ n“]}星期一3月25 20:47:29 UTC 2019:由于以下原因,Lambda执行失败,状态为200 客户功能错误:“用户”。 Lambda请求ID: f7955f74-e608-4b10-b216-4e4acf682307 Mon Mar 25 20:47:29 UTC 2019: 方法完成,状态:502
答案 0 :(得分:1)
这是因为当event
对象来自API Gateway时,它具有一些额外的信息。它不像您用来从控制台进行测试的JSON一样简单。
您需要先访问body
对象,然后再访问JSON对象。
这是来自API网关的事件的样子:
{
"path": "/test/hello",
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, lzma, sdch, br",
"Accept-Language": "en-US,en;q=0.8",
"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": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
"Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==",
"X-Forwarded-For": "192.168.100.1, 192.168.1.1",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"pathParameters": {
"proxy": "hello"
},
"requestContext": {
"accountId": "123456789012",
"resourceId": "us4z18",
"stage": "test",
"requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9",
"identity": {
"cognitoIdentityPoolId": "",
"accountId": "",
"cognitoIdentityId": "",
"caller": "",
"apiKey": "",
"sourceIp": "192.168.100.1",
"cognitoAuthenticationType": "",
"cognitoAuthenticationProvider": "",
"userArn": "",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
"user": ""
},
"resourcePath": "/{proxy+}",
"httpMethod": "GET",
"apiId": "wt6mne2s9k"
},
"resource": "/{proxy+}",
"httpMethod": "GET",
"queryStringParameters": {
"name": "me"
},
"stageVariables": {
"stageVarName": "stageVarValue"
},
"body": "'{\"user\":\"john\",\"pwd\":\"pwd1\"}'"
}
请记住,API网关中的body
总是字符串化的,因此,如果要访问它,首先需要使用json.loads(event["body"])
解析此JSON字符串。
请记住,如我们在this answer上所讨论的那样,当返回API网关时,必须对响应的主体进行字符串化处理。
您可以在docs
中查看从API网关发送的事件答案 1 :(得分:1)
@Thales Minussi使我得到了这个答案,但是我从回答中得到的关键与他的建议不同,但是他的建议对我有所帮助,所以我接受它作为答案
我得到了这个回应。 body
键以null
的形式出现。但是有queryStringParameters
{
"resource": "/match_creds",
"path": "/match_creds",
"httpMethod": "GET",
"headers": null,
"multiValueHeaders": null,
"queryStringParameters": {
"pwd": "pwd1",
"user": "JOHN"
},
"multiValueQueryStringParameters": {
"pwd": [
"pwd1"
],
"user": [
"JOHN"
]
},
"pathParameters": null,
"stageVariables": null,
"requestContext": {
"path": "/match_creds",
"accountId": "",
"resourceId": "",
"stage": "test-invoke-stage",
"domainPrefix": "testPrefix",
"requestId": "",
"identity": {
"cognitoIdentityPoolId": null,
"cognitoIdentityId": null,
"apiKey": "test-invoke-api-key",
"cognitoAuthenticationType": null,
"userArn": "",
"apiKeyId": "test-invoke-api-key-id",
"userAgent": "",
"accountId": "",
"caller": "",
"sourceIp": "test-invoke-source-ip",
"accessKey": "",
"cognitoAuthenticationProvider": null,
"user": ""
},
"domainName": "testPrefix.testDomainName",
"resourcePath": "/match_creds",
"httpMethod": "GET",
"extendedRequestId": "",
"apiId": ""
},
"body": null,
"isBase64Encoded": false
}
我将功能更改为
import json
def lambda_handler(event, context):
json_data = event["queryStringParameters"]
user = json_data["user"]
return {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps(user)
}
答案 2 :(得分:0)
您需要激活“集成请求”下的“使用Lambda代理集成”设置。