使用 post 请求调用 API 时获得 500 响应
Getting 500 response while invoking API with post request
我已经部署了集成 API 的无服务器功能。下面是代码
Serverless.yml
service: serverless-rest-api-with-dynamodb
provider:
name: aws
runtime: python3.8
region: eu-west-1
environment:
DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage}
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
logs: true
functions:
myFunc:
handler: handler.customer
events:
- http:
path: customer_details
method: post
resources:
Resources:
TodosDynamoDbTable:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
TableName: CustomerTablev1
AttributeDefinitions:
- AttributeName: id
AttributeType: S
- AttributeName: CustomerName
AttributeType: S
KeySchema:
-
AttributeName: id
KeyType: HASH
- AttributeName: CustomerName
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
handler.py
import json
def customer(event, context):
postData= event['body']
return {
'statusCode': 200,
'body': "Hello Post accepted",
"content-type": "application/json"
}
下面是我为 api 添加的调用 lambda 函数的权限
{
"Policy": "{\"Version\":\"2012-10-17\",\"Id\":\"default\",\"Statement\":
[{\"Sid\":\"serverless-rest-api-with-dynamodb-dev-MyFuncLambdaPermissionApiGateway-dfdd22\",
\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},
\"Action\":\"lambda:InvokeFunction\",
\"Resource\":\"arn:aws:lambda:eu-west-1:##3d64543:function:serverless-rest-api-with-dynamodb-dev-myFunc\",
\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:eu-west-1:##343d64543:tmx8paevk3/*/*\"}}},
{\"Sid\":\"###23232dfecfb\",
\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},
\"Action\":\"lambda:InvokeFunction\",
\"Resource\":\"arn:aws:lambda:eu-west-1:##3d64543:function:serverless-rest-api-with-dynamodb-dev-myFunc\",
\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:eu-west-1:##3d64543:tmx8paevk3/*/POST/customer_details\"}}},
{\"Sid\":\"apigateway\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},
\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:eu-west-1:##3d64543:function:serverless-rest-api-with-dynamodb-dev-myFunc\"}]}",
"RevisionId": "##3d64543ddf-4ecdfe"
}
我用正文请求调用了 api,例如:
{
“姓名”:“123”
}
下面是日志
Verifying Usage Plan for request: 33434-df-sdf##. API Key: API Stage: tmx8paevk3/dev
API Key authorized because method 'POST /customer_details' does not require API Key. Request will not contribute to throttle or quota limits
Usage Plan check succeeded for API Key and API Stage tmx8paevk3/dev
Starting execution for request: 343-f-er-###
HTTP Method: POST, Resource Path: /customer_details
Method request path:
{}
(c3434-ffg34--sd2qw) Method request query string:
{}
Method request headers: {Accept=application/json, CloudFront-Viewer-Country=IN, CloudFront-Forwarded-Proto=https, CloudFront-Is-Tablet-Viewer=false, CloudFront-Is-Mobile-Viewer=false, User-Agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36, X-Forwarded-Proto=https, CloudFront-Is-SmartTV-Viewer=false, Host=tmx8paevk3.execute-api.eu-west-1.amazonaws.com, Accept-Encoding=gzip, deflate, X-Forwarded-Port=443, X-Amzn-Trace-Id=Root=1-5e08179b-231fd1c4058eaaa020eff0d0, Via=1.1 da86ace2d9b441802dcc77e25582499b.cloudfront.net (CloudFront), X-Amz-Cf-Id=oXgrxNvE97x-3FvOB7_85BawEcIIGe5Puzy6S9XIiKSDj8yLZQv-Ig==, X-Forwarded-For=117.204.125.144, 52.46.37.72, content-type=application/json, Accept-Language=en-US,en;q=0.8, CloudFront-Is-Desktop-Viewer=true}
Method request body before transformations:
{
"name": "test"
}
Endpoint request URI: https://lambda.eu-west-1.amazonaws.com/2013-233-32/functions/arn:aws:lambda:eu-west-1:3d##:function:serverless-rest-api-with-dynamodb-dev-myFunc/invocations
Endpoint request headers: {x-amzn-lambda-integration-tag=##sdsd-sd23, Authorization=************************************************************************************************************************************************************************************************************************************************************************************************************************d9c3f1, X-Amz-Date=20191229T030355Z, x-amzn-apigateway-api-id=tmx8paevk3, X-Amz-Source-Arn=arn:aws:execute-api:eu-west-1:7###343434:tmx8paevk3/dev/POST/customer_details, Accept=application/json, User-Agent=AmazonAPIGateway_tm##we, X-Amz-Security-Token=I###12323/D######/xfP2323######//////////8B#######/334####/dsd## [TRUNCATED]
Endpoint request body after transformations:
{
"name": "test"
}
Sending request to https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-west-1:####:function:serverless-rest-api-with-dynamodb-dev-myFunc/invocations
Received response. Status: 200, Integration latency: 263 ms
Endpoint response headers: {Date=Sun, 29 Dec 2019 03:03:56 GMT, Content-Type=application/json, Content-Length=86, Connection=keep-alive, x-amzn-RequestId=3443D-23#, x-amzn-Remapped-Content-Length=0, X-Amz-Executed-Version=$LATEST, X-Amzn-Trace-Id=23d=-dere###;sampled=0}
Endpoint response body before transformations:
{
"statusCode": 200,
"body": "Hello Post accepted",
"content-type": "application/json"
}
Execution failed due to configuration error: Output mapping refers to an invalid method response: 200
Method completed with status: 500
AWS Integration Endpoint RequestId : 323d-fer-vsd###
但它仍然是 returns 500 内部错误。我搜索了不同的方法来获得解决方案,每个人都说这只是因为缺少 API 必须调用 lambda 的权限。由于我已经向 API 提供了许可,我想知道具体是什么,对此有什么解决方案?
感谢是否有人可以提供帮助?
您的回复body是这里的问题:
{
'statusCode': 200,
'body': "Hello Post accepted",
"content-type": "application/json"
}
它应该是(因为您将 header 设置为 json 并传递普通文本):
{
'statusCode': 200,
'body': json.dumps({"reply":"Hello Post accepted"}),
"content-type": "application/json"
}
我已经审查并测试了您的无服务器框架代码,在稍作修改后,我能够通过进行以下更改来使设置正常工作:
handler.py
import json
def hello(event, context):
postData = event['body']
# Prepare a response dictionary as required by API Gateway
response = {
"statusCode": 200,
"isBase64Encoded": False,
"headers": {},
"content-type": "application/json",
"body": json.dumps(postData)
}
return response
Serverless.yml
service: HelloWorld
provider:
name: aws
runtime: python2.7
region: eu-west-1
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
logs: true
environment:
DYNAMODB_TABLE: '${self:service}-${opt:stage, self:provider.stage}'
functions:
hello:
handler: handler.hello
events:
- http:
path: customers-details
method: POST
integration: LAMBDA # Add this line
resources:
Resources:
TodosDynamoDbTable:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
TableName: CustomerTablev1
AttributeDefinitions:
- AttributeName: id
AttributeType: S
- AttributeName: CustomerName
AttributeType: S
KeySchema:
-
AttributeName: id
KeyType: HASH
- AttributeName: CustomerName
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
卷曲测试
要求:
curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"name":"syumaK"}' --url https://z0uu17yp6f.execute-api.eu-west-1.amazonaws.com/dev/customers-details
响应:
{"body": "{\"name\": \"syumaK\"}", "headers": {}, "content-type": "application/json", "isBase64Encoded": false, "statusCode": 200}%
要点是,在使用 Serverless Framework 和 AWS Lambda(Lambda 代理)时,您必须添加到以下行在您的 serverless.yml 事件中:
integration: LAMBDA
希望对您有所帮助!
我已经部署了集成 API 的无服务器功能。下面是代码
Serverless.yml
service: serverless-rest-api-with-dynamodb
provider:
name: aws
runtime: python3.8
region: eu-west-1
environment:
DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage}
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
logs: true
functions:
myFunc:
handler: handler.customer
events:
- http:
path: customer_details
method: post
resources:
Resources:
TodosDynamoDbTable:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
TableName: CustomerTablev1
AttributeDefinitions:
- AttributeName: id
AttributeType: S
- AttributeName: CustomerName
AttributeType: S
KeySchema:
-
AttributeName: id
KeyType: HASH
- AttributeName: CustomerName
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
handler.py
import json
def customer(event, context):
postData= event['body']
return {
'statusCode': 200,
'body': "Hello Post accepted",
"content-type": "application/json"
}
下面是我为 api 添加的调用 lambda 函数的权限
{
"Policy": "{\"Version\":\"2012-10-17\",\"Id\":\"default\",\"Statement\":
[{\"Sid\":\"serverless-rest-api-with-dynamodb-dev-MyFuncLambdaPermissionApiGateway-dfdd22\",
\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},
\"Action\":\"lambda:InvokeFunction\",
\"Resource\":\"arn:aws:lambda:eu-west-1:##3d64543:function:serverless-rest-api-with-dynamodb-dev-myFunc\",
\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:eu-west-1:##343d64543:tmx8paevk3/*/*\"}}},
{\"Sid\":\"###23232dfecfb\",
\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},
\"Action\":\"lambda:InvokeFunction\",
\"Resource\":\"arn:aws:lambda:eu-west-1:##3d64543:function:serverless-rest-api-with-dynamodb-dev-myFunc\",
\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:eu-west-1:##3d64543:tmx8paevk3/*/POST/customer_details\"}}},
{\"Sid\":\"apigateway\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},
\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:eu-west-1:##3d64543:function:serverless-rest-api-with-dynamodb-dev-myFunc\"}]}",
"RevisionId": "##3d64543ddf-4ecdfe"
}
我用正文请求调用了 api,例如: { “姓名”:“123” }
下面是日志
Verifying Usage Plan for request: 33434-df-sdf##. API Key: API Stage: tmx8paevk3/dev
API Key authorized because method 'POST /customer_details' does not require API Key. Request will not contribute to throttle or quota limits
Usage Plan check succeeded for API Key and API Stage tmx8paevk3/dev
Starting execution for request: 343-f-er-###
HTTP Method: POST, Resource Path: /customer_details
Method request path:
{}
(c3434-ffg34--sd2qw) Method request query string:
{}
Method request headers: {Accept=application/json, CloudFront-Viewer-Country=IN, CloudFront-Forwarded-Proto=https, CloudFront-Is-Tablet-Viewer=false, CloudFront-Is-Mobile-Viewer=false, User-Agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36, X-Forwarded-Proto=https, CloudFront-Is-SmartTV-Viewer=false, Host=tmx8paevk3.execute-api.eu-west-1.amazonaws.com, Accept-Encoding=gzip, deflate, X-Forwarded-Port=443, X-Amzn-Trace-Id=Root=1-5e08179b-231fd1c4058eaaa020eff0d0, Via=1.1 da86ace2d9b441802dcc77e25582499b.cloudfront.net (CloudFront), X-Amz-Cf-Id=oXgrxNvE97x-3FvOB7_85BawEcIIGe5Puzy6S9XIiKSDj8yLZQv-Ig==, X-Forwarded-For=117.204.125.144, 52.46.37.72, content-type=application/json, Accept-Language=en-US,en;q=0.8, CloudFront-Is-Desktop-Viewer=true}
Method request body before transformations:
{
"name": "test"
}
Endpoint request URI: https://lambda.eu-west-1.amazonaws.com/2013-233-32/functions/arn:aws:lambda:eu-west-1:3d##:function:serverless-rest-api-with-dynamodb-dev-myFunc/invocations
Endpoint request headers: {x-amzn-lambda-integration-tag=##sdsd-sd23, Authorization=************************************************************************************************************************************************************************************************************************************************************************************************************************d9c3f1, X-Amz-Date=20191229T030355Z, x-amzn-apigateway-api-id=tmx8paevk3, X-Amz-Source-Arn=arn:aws:execute-api:eu-west-1:7###343434:tmx8paevk3/dev/POST/customer_details, Accept=application/json, User-Agent=AmazonAPIGateway_tm##we, X-Amz-Security-Token=I###12323/D######/xfP2323######//////////8B#######/334####/dsd## [TRUNCATED]
Endpoint request body after transformations:
{
"name": "test"
}
Sending request to https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-west-1:####:function:serverless-rest-api-with-dynamodb-dev-myFunc/invocations
Received response. Status: 200, Integration latency: 263 ms
Endpoint response headers: {Date=Sun, 29 Dec 2019 03:03:56 GMT, Content-Type=application/json, Content-Length=86, Connection=keep-alive, x-amzn-RequestId=3443D-23#, x-amzn-Remapped-Content-Length=0, X-Amz-Executed-Version=$LATEST, X-Amzn-Trace-Id=23d=-dere###;sampled=0}
Endpoint response body before transformations:
{
"statusCode": 200,
"body": "Hello Post accepted",
"content-type": "application/json"
}
Execution failed due to configuration error: Output mapping refers to an invalid method response: 200
Method completed with status: 500
AWS Integration Endpoint RequestId : 323d-fer-vsd###
但它仍然是 returns 500 内部错误。我搜索了不同的方法来获得解决方案,每个人都说这只是因为缺少 API 必须调用 lambda 的权限。由于我已经向 API 提供了许可,我想知道具体是什么,对此有什么解决方案? 感谢是否有人可以提供帮助?
您的回复body是这里的问题:
{
'statusCode': 200,
'body': "Hello Post accepted",
"content-type": "application/json"
}
它应该是(因为您将 header 设置为 json 并传递普通文本):
{
'statusCode': 200,
'body': json.dumps({"reply":"Hello Post accepted"}),
"content-type": "application/json"
}
我已经审查并测试了您的无服务器框架代码,在稍作修改后,我能够通过进行以下更改来使设置正常工作:
handler.py
import json
def hello(event, context):
postData = event['body']
# Prepare a response dictionary as required by API Gateway
response = {
"statusCode": 200,
"isBase64Encoded": False,
"headers": {},
"content-type": "application/json",
"body": json.dumps(postData)
}
return response
Serverless.yml
service: HelloWorld
provider:
name: aws
runtime: python2.7
region: eu-west-1
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
logs: true
environment:
DYNAMODB_TABLE: '${self:service}-${opt:stage, self:provider.stage}'
functions:
hello:
handler: handler.hello
events:
- http:
path: customers-details
method: POST
integration: LAMBDA # Add this line
resources:
Resources:
TodosDynamoDbTable:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
TableName: CustomerTablev1
AttributeDefinitions:
- AttributeName: id
AttributeType: S
- AttributeName: CustomerName
AttributeType: S
KeySchema:
-
AttributeName: id
KeyType: HASH
- AttributeName: CustomerName
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
卷曲测试
要求:
curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"name":"syumaK"}' --url https://z0uu17yp6f.execute-api.eu-west-1.amazonaws.com/dev/customers-details
响应:
{"body": "{\"name\": \"syumaK\"}", "headers": {}, "content-type": "application/json", "isBase64Encoded": false, "statusCode": 200}%
要点是,在使用 Serverless Framework 和 AWS Lambda(Lambda 代理)时,您必须添加到以下行在您的 serverless.yml 事件中:
integration: LAMBDA
希望对您有所帮助!