英文:
API Gateway returning 500 when lambda and authorizer return 200
问题
我有一个配置了Lambda代理集成的POST方法,集成在API Gateway中。还有一个设置用于验证请求的授权器。当我发送POST请求到该方法时,即使Lambda和授权器都返回2xx状态,我仍然收到500内部服务器错误。以下是来自API Gateway的日志:
{
"stage": "v1",
"request_id": "b3d88fff-896a-49f0-a4d6-87bcea71da65",
"api_id": "25a3fslb53",
"resource_path": "/testResource",
"resource_id": "vvvvvvv",
"http_method": "POST",
"request_time": "06/Feb/2023:04:17:21 +0000",
"status_override": "-",
"status": "500",
"response_length": "36",
"response_latency": "2121",
"lambda": {
"status": "202",
"latency": "47",
"request_id": "56dd16c1-07df-4d35-9dda-0255e0ff9c87",
"error": "-"
},
"authorizer": {
"status": "200",
"latency": "2069",
"request_id": "9026e600-f933-4b1f-8e08-0640c9872a42",
"error": "-"
},
"error": "Internal server error"
}
以下是我的API Gateway配置。请注意,我使用了Open API规范来定义大部分内容。
ApiGateway:
Type: AWS::Serverless::Api
Properties:
Name: !Sub "${StageName} Store Comms - Call History Service Gateway"
EndpointConfiguration:
Type: REGIONAL
AccessLogSetting:
DestinationArn: !GetAtt CallHistoryAPILogs.Arn
Format: '{ "stage":"$context.stage","request_id":"$context.requestId","api_id":"$context.apiId","resource_path":"$context.resourcePath","resource_id":"$context.resourceId","http_method":"$context.httpMethod","request_time":"$context.requestTime","status_override":"$context.responseOverride.status","status":"$context.status","response_length":"$context.responseLength","response_latency":"$context.responseLatency","lambda":{"status":"$context.integrationStatus","latency":"$context.integrationLatency","request_id":"$context.integration.requestId","error":"$context.integrationErrorMessage"},"authorizer":{"status":"$context.authorizer.status","latency":"$context.authorizer.latency","request_id":"$context.authorizer.requestId","error":"$context.authorizer.error"},"error":"$context.error.message"}'
DefinitionBody:
openapi: 3.0.3
info:
title: 'Call History APIs'
version: 1.0.0
paths:
/testResource:
post:
parameters:
- name: 'xxxxx'
in: 'query'
required: true
schema:
type: 'string'
- name: 'yyyyyy'
in: 'query'
required: true
schema:
type: 'string'
x-amazon-apigateway-integration:
type: aws
requestParameters:
integration.request.header.X-Amz-Invocation-Type: '''Event'''
integration.request.querystring.store_id: "method.request.querystring.xxxxx"
integration.request.querystring.yyyyyy: "method.request.querystring.yyyyyy"
requestTemplates:
"application/json": >-
{ "body":"$util.escapeJavaScript($input.body).replaceAll('\'','')",
"path":"testResource", "httpMethod":"POST", "queryStringParameters": {
"xxxxx": "$input.params('xxxxx')",
"yyyyyy": "$input.params('yyyyyy')"} }
httpMethod: POST
uri: !Sub 'arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CallHistoryFunction.Arn}/invocations'
responses:
'202':
statusCode: '202'
selectionPattern: ""
responses:
'202':
description: call history successfully saved
security:
- Authorizer: []
components:
securitySchemes:
Authorizer:
type: "apiKey"
name: "Unused"
in: "header"
x-amazon-apigateway-authtype: "custom"
x-amazon-apigateway-authorizer:
authorizerUri: "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:xxxxx:function:xxxxxx4d/invocations"
authorizerResultTtlInSeconds: 300
identitySource: "method.request.header.X-Authorization, method.request.header.X-Date"
type: "request"
CacheClusterEnabled: true
CacheClusterSize: "0.5"
MethodSettings:
- ResourcePath: "/testResource"
CachingEnabled: false
HttpMethod: "POST"
StageName: v1
GatewayResponses:
UNAUTHORIZED:
StatusCode: 401
ResponseParameters:
Headers:
Access-Control-Allow-Origin: "'*'"
ACCESS_DENIED:
StatusCode: 403
ResponseParameters:
Headers:
Access-Control-Allow-Origin: "'*'"
DEFAULT_5XX:
StatusCode: 500
ResponseParameters:
Headers:
Access-Control-Allow-Origin: "'*'"
RESOURCE_NOT_FOUND:
StatusCode: 404
ResponseParameters:
Headers:
Access-Control-Allow-Origin: "'*'"
如果您需要进一步的帮助或翻译其他部分,请告诉我。
英文:
I have a POST method with lambda proxy integration configured in API Gateway. There's also an authorizer set to verify the requests.
When I send a POST request to the method I am getting 500 Internal Server error even though Lambda and Authorizer reply with a 2xx. Here's the log from API Gateway:
"stage": "v1",
"request_id": "b3d88fff-896a-49f0-a4d6-87bcea71da65",
"api_id": "25a3fslb53",
"resource_path": "/testResource",
"resource_id": "vvvvvvv",
"http_method": "POST",
"request_time": "06/Feb/2023:04:17:21 +0000",
"status_override": "-",
"status": "500",
"response_length": "36",
"response_latency": "2121",
"lambda": {
"status": "202",
"latency": "47",
"request_id": "56dd16c1-07df-4d35-9dda-0255e0ff9c87",
"error": "-"
},
"authorizer": {
"status": "200",
"latency": "2069",
"request_id": "9026e600-f933-4b1f-8e08-0640c9872a42",
"error": "-"
},
"error": "Internal server error"
}
Here's my config for API Gateway. Note that I am using Open API specification to define most of it.
ApiGateway:
Type: AWS::Serverless::Api
Properties:
Name: !Sub "${StageName} Store Comms - Call History Service Gateway"
EndpointConfiguration:
Type: REGIONAL
AccessLogSetting:
DestinationArn: !GetAtt CallHistoryAPILogs.Arn
Format: '{"stage":"$context.stage","request_id":"$context.requestId","api_id":"$context.apiId","resource_path":"$context.resourcePath","resource_id":"$context.resourceId","http_method":"$context.httpMethod","request_time":"$context.requestTime","status_override":"$context.responseOverride.status","status":"$context.status","response_length":"$context.responseLength","response_latency":"$context.responseLatency","lambda":{"status":"$context.integrationStatus","latency":"$context.integrationLatency","request_id":"$context.integration.requestId","error":"$context.integrationErrorMessage"},"authorizer":{"status":"$context.authorizer.status","latency":"$context.authorizer.latency","request_id":"$context.authorizer.requestId","error":"$context.authorizer.error"},"error":"$context.error.message"}'
DefinitionBody:
openapi: 3.0.3
info:
title: 'Call History APIs'
version: 1.0.0
paths:
/testResource:
post:
parameters:
- name: 'xxxxx'
in: 'query'
required: true
schema:
type: 'string'
- name: 'yyyyyy'
in: 'query'
required: true
schema:
type: 'string'
x-amazon-apigateway-integration:
type: aws
requestParameters:
integration.request.header.X-Amz-Invocation-Type: '''Event'''
integration.request.querystring.store_id: "method.request.querystring.xxxxx"
integration.request.querystring.yyyyyy: "method.request.querystring.yyyyyy"
requestTemplates:
"application/json": >-
{ "body":"$util.escapeJavaScript($input.body).replaceAll("\\'","'")",
"path":"testResource", "httpMethod":"POST", "queryStringParameters": {
"xxxxx": "$input.params('xxxxx')",
"yyyyyy": "$input.params('yyyyyy')" } }
httpMethod: POST
uri: !Sub 'arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CallHistoryFunction.Arn}/invocations'
responses:
'202':
statusCode: '202'
selectionPattern: ""
responses:
'202':
description: call history successfully saved
security:
- Authorizer: []
components:
securitySchemes:
Authorizer:
type: "apiKey"
name: "Unused"
in: "header"
x-amazon-apigateway-authtype: "custom"
x-amazon-apigateway-authorizer:
authorizerUri: "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:xxxxx:function:xxxxxx4d/invocations"
authorizerResultTtlInSeconds: 300
identitySource: "method.request.header.X-Authorization, method.request.header.X-Date"
type: "request"
CacheClusterEnabled: true
CacheClusterSize: "0.5"
MethodSettings:
- ResourcePath: "/testResource"
CachingEnabled: false
HttpMethod: "POST"
StageName: v1
GatewayResponses:
UNAUTHORIZED:
StatusCode: 401
ResponseParameters:
Headers:
Access-Control-Allow-Origin: "'*'"
ACCESS_DENIED:
StatusCode: 403
ResponseParameters:
Headers:
Access-Control-Allow-Origin: "'*'"
DEFAULT_5XX:
StatusCode: 500
ResponseParameters:
Headers:
Access-Control-Allow-Origin: "'*'"
RESOURCE_NOT_FOUND:
StatusCode: 404
ResponseParameters:
Headers:
Access-Control-Allow-Origin: "'*'"
答案1
得分: 2
我弄清楚了。 集成设置没有正确设置:
我将这个更改为
responses:
'202':
statusCode: '202'
selectionPattern: ""
变成了
responses:
default:
statusCode: "202"
还要注意,与lambda集成的情况下,integration的httpMethod应始终为POST,无论API的方法是什么。
英文:
I figured this out. The integration settings weren't set right:
I changed this
responses:
'202':
statusCode: '202'
selectionPattern: ""
to this
responses:
default:
statusCode: "202"
Note also that the httpMethod for the integration should always be POST in case of an integration with lambda, no matter what the method is for your API.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论