首页 文章

API网关模拟集成失败,500

提问于
浏览
3

我有一个方法/资源的API网关集成,当我从API调用它时,它工作,但实际上我没有调用它:

$ aws apigateway test-invoke-method --rest-api-id $REST_API_ID \
    --resource-id $RESOURCE_ID --http-method GET | jq -r .log,.body

这很好,我得到以下输出:

Tue May 16 17:46:42 UTC 2017 : Starting execution for request: test-invoke-request
Tue May 16 17:46:42 UTC 2017 : HTTP Method: GET, Resource Path: /status.json
Tue May 16 17:46:42 UTC 2017 : Method request path: {}
Tue May 16 17:46:42 UTC 2017 : Method request query string: {}
Tue May 16 17:46:42 UTC 2017 : Method request headers: {}
Tue May 16 17:46:42 UTC 2017 : Method request body before transformations:
Tue May 16 17:46:42 UTC 2017 : Endpoint response body before transformations:
Tue May 16 17:46:42 UTC 2017 : Endpoint response headers: {}
Tue May 16 17:46:42 UTC 2017 : Method response body after transformations: { "statusCode": 200 }
Tue May 16 17:46:42 UTC 2017 : Method response headers: {Content-Type=application/json}
Tue May 16 17:46:42 UTC 2017 : Successfully completed execution
Tue May 16 17:46:42 UTC 2017 : Method completed with status: 200

{ "statusCode": 200 }

但是,我无法通过我的URL访问此内容,即 api.naftuli.wtf/v1/status.json . 我在 glhfstablev1 定义了阶段,因此通过替换它,您将看到不同的响应 . 我只是想要一个返回200 JSON blob的虚拟响应 .

我的Terraform资源是here as a Gist . 希望这完全显示我的API网关配置 .

如果我测试从CLI或Web控制台调用它,我会得到预期的结果 . 但是,如果我在api.naftuli.wtf处从我部署的API卷曲这个,我没有得到任何好处:

$ for stage in glhf stable v1 ; do 
>   url="https://api.naftuli.wtf/${stage}/status.json"
>   echo "${url}:" 
>   curl -i -H 'Content-Type: application/json' \
>     https://api.naftuli.wtf/${stage}/status.json
>   echo -e '\n
> done
https://api.naftuli.wtf/glhf/status.json:
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
Content-Length: 36
Connection: keep-alive
Date: Tue, 16 May 2017 21:41:38 GMT
x-amzn-RequestId: 712ba52b-3a80-11e7-9fec-b79b62d3bf7f
X-Cache: Error from cloudfront
Via: 1.1 da7a5d0ed7f424609000879e43743066.cloudfront.net (CloudFront)
X-Amz-Cf-Id: hBwlbPCP9n2rlz53I-Qb9KoffHB_FoxUCZUaJYNnU3XhCWuMpQTP1Q==

{"message": "Internal server error"}

https://api.naftuli.wtf/stable/status.json:
HTTP/1.1 403 Forbidden
Content-Type: application/json
Content-Length: 23
Connection: keep-alive
Date: Tue, 16 May 2017 21:41:38 GMT
x-amzn-RequestId: 71561066-3a80-11e7-9b00-6700be628328
x-amzn-ErrorType: ForbiddenException
X-Cache: Error from cloudfront
Via: 1.1 0c146399837c7d36c1f0f9d2636f8cf8.cloudfront.net (CloudFront)
X-Amz-Cf-Id: ITX765xD8s4sNuOdXaJ2kPvqPo-w_dsQK3Sq_No130FAHxFuoVhO8w==

{"message":"Forbidden"}

https://api.naftuli.wtf/v1/status.json:
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
Content-Length: 36
Connection: keep-alive
Date: Tue, 16 May 2017 21:41:39 GMT
x-amzn-RequestId: 7185fa99-3a80-11e7-a3b1-2f9e659fc361
X-Cache: Error from cloudfront
Via: 1.1 586f1a150b4ba39f3a668b8055d4d5ea.cloudfront.net (CloudFront)
X-Amz-Cf-Id: dvnOa1s-YlwLSNzBfVyx5tSL6XrjFJM4_fES7MyTofykB3ReU5R1fg==

{"message": "Internal server error"}

我对阶段的理解是它们是所有API资源可用的基本路径的附加路径前缀 . 如果我有一个名为 v1 的阶段,路径为 /v1 ,我希望 status.json 的API网关资源基本上映射到 /v1 ,产生 /v1/status.json .

我可能误解了API网关基本路径映射和阶段是如何工作的,但CloudWatch告诉我该呼叫至少正在发生,尽管由于一些不明原因而失败:

21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) Verifying Usage Plan for request: c5be3842-6af4-4725-a34f-d6eea8042d17. API Key: API Stage: tcips69qx2/prod_v1
21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) API Key authorized because method 'GET /status.json' does not require API Key. Request will not contribute to throttle or quota limits
21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) Usage Plan check succeeded for API Key and API Stage tcips69qx2/prod_v1
21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) Starting execution for request: c5be3842-6af4-4725-a34f-d6eea8042d17
21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) HTTP Method: GET, Resource Path: /v1/status.json
21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) Execution failed due to configuration error: statusCode should be an integer which defined in request template
21:41:39(c5be3842-6af4-4725-a34f-d6eea8042d17) Method completed with status: 500

显然,只有V1阶段的流量才能通过CloudWatch日志 . 我在某个地方有一个错误的配置,我似乎无法找到它 .

3 回答

  • 0

    您可以尝试将集成请求设置中的请求模板更改为:

    {
      "statusCode": 200
    }
    

    API网关在integration request template的响应中查找要返回的状态代码 . 响应由集成响应中的映射模板生成 . 我可以从您的terraform设置中看到您正在加载集成请求模板中的输出json文件 . 这是内容API网关不期望的 .

  • 7

    您的配置至少存在两个明显的问题 .

    首先,您的三个基本路径映射之一不会尝试调用您的API . 请注意,基本路径不必与您的阶段名称相同,但如果您愿意,它们可以是相同的 . 由于基本路径映射包括基本路径和阶段名称,因此API网关期望调用路径包含基本路径映射而不是阶段,因此它将路径的[glhf stable v1]部分解释为基本路径并查找用于相应的基本路径映射条目,以确定要使用的API和阶段 . 这适用于返回500的v1和glhf基本路径(表示不同的问题) . 稳定的基本路径(在https://api.naftuli.wtf/stable/status.json中)返回403 Forbidden,因为没有为域名api.naftuli.wtf定义"stable"的基本路径 . 稳定阶段映射到"latest"基本路径,因此调用https://api.naftuli.wtf/latest/status.json应该是调用稳定阶段的方法 . 这不知道为什么 . 如果你告诉我你在哪个区域运行,我可以查看配置并进行更多挖掘 .

    第二个问题由CloudWatch日志中的以下条目指示:

    由于配置错误,执行失败:statusCode应该是在请求模板中定义的整数

    您是否可以检查您的集成请求模板(在“$ {file(”$ /files/status.json“)}”)中的引用文件中包含“statusCode:200”作为顶级属性 .

    我还发现,您对请求模板和响应模板使用相同的文件时会感到惊讶 .

  • 1

    这里特别奇怪的是,修复只是为每个阶段使用AWS CLI创建部署 . 显然,Terraform没有在更改时更新或重新进行部署,因此我的更改从未得到过 .

相关问题