AWS API网关代理响应失败/被丢弃

时间:2016-11-01 10:25:54

标签: api amazon-web-services curl proxy aws-api-gateway

问题

AWS API网关代理在使用Postman时没有从我的后端服务传回响应,但是在curl上工作

描述

我有一个后端服务,我想通过AWS API网关公开。在这种情况下,网关的使用纯粹是作为HTTP代理。所以,

  1. 创建了新的API
  2. 将资源设置为"代理"使用ANY
  3. 给我的后端服务地址
  4. 已部署(无需Auth,但需要API密钥)
  5. 可以从部署阶段网址成功调用我的后端服务
  6. 使用CA证书创建自定义域
  7. 在我的DNS提供商上创建了别名
  8. 1小时后,域名正在启动并指向云端
  9. 问题

    我拨打了自定义域名

    1. API网关收到它
    2. 呼叫记录在云监视日志中,
    3. 它击中了我的后端。
    4. 后端回复了API网关。
    5. 但是,在我的邮递员身上,我看到"无法得到任何回复"

      但是,如果我通过curl尝试此操作,我会收到由我的后端发送的预期回复。所以,不清楚的部分是 -

      1. 邮差调用或基于GET的普通浏览器网址栏到我的终端有什么问题?

      2. 为什么卷曲成功?

      3. 并且,对于我的API网关端点,我已将API密钥设置为必需。我创建了一个API密钥并将其分配给API。有趣的是,即使我没有传递API密钥,卷曲调用仍然是成功的。为什么API网关允许这样的呼叫?

      4. 对我来说另一个令人困惑的问题是,我必须在我用于API版本控制的AcceptContent-Type中传递自定义值。

      5. 例如:Accept: application/json-v1失败,但Accept: application/xml-v1正在运作。

        我认为这与价值有关,因为API Gateway并不喜欢它。

        我已经仔细阅读了文档,仍然无法找到所有这些问题的任何合理解释。我错过了什么导致这些奇怪的问题?到目前为止,我的google fu还不足以解决这个问题。

        请帮助或同等地向我指出AWS网关中的特定文档,这些文档可以帮助解决我可能在这些主题上遗漏的这个或任何讨论主题。

        至少得到其中一个的答案会让我明白我的方法。

        谢谢别人!

3 个答案:

答案 0 :(得分:7)

快速回答:添加标题"CREATE TABLE " & dbName & ".dbo.MyTable ( ..."

使用AWS api-gateway时遇到了完全相同的问题。在我的情况下,解决方案是从邮递员添加标头Accept-Encoding:identity或配置AWS API以默认将其发送到我的后端。

当我直接从邮递员调用我的后端时,我可以将标题设置为Accept-Encoding:identity,邮递员将正确显示响应,但是当我通过AWS执行此操作时,似乎是一个我没有问题的问题能够解决。将提到的标题设置为gzip将指示后端不要修改响应(或应用标识功能)。

答案 1 :(得分:1)

  1. curl和Postman / browser都最终向您的API网关发出HTTP请求,因此任务是弄清楚请求中的差异。如果您使用-v标志运行curl,您将获得详细输出,其中包含随请求一起发送的所有标头。邮差/浏览器应该有类似的东西,请比较它们,你应该找到一个区别。 另外,为了消除自定义域可能存在的问题,您是否尝试过向非自定义域(* .execute-api)URI发出请求?

  2. 见1.

  3. 确保您的代理方法选中了“需要API密钥”复选框。
  4. 如果您正在使用映射模板转换,则必须为希望从客户端请求接收的每种内容类型设置模板。如果您未使用转换,请确保WHEN_NO_TEMPLATE(“如果在控制台UI中未定义模板(推荐)”),则会为集成请求选择直通行为。 请参阅:12

答案 2 :(得分:0)

我遇到了同样的问题。

适用于我们的用例的解决方案是禁用应用程序服务器上的压缩。然后从AWS API Gateway设置启用Content Encoding功能:

enter image description here

不要忘记从resources部分重新部署您的API阶段!

对于在AWS Lambda中运行并通过API网关proxy进行访问的Express.js API端点,您可以将app.js修改如下:

   const compression = require('compression');
   if (!process.env.LAMBDA_TASK_ROOT) {
      app(compression()); // compression is only enabled when not in Lambda
   }