AWS API Gateway正文映射通配符

时间:2016-09-13 15:33:00

标签: aws-lambda aws-api-gateway

我在AWS API Gateway上设置了一个API,该API使用内容协商来提供两种方法来获取某些数据。

我的问题是,因为default Content-Type header appears to be application/json,下面的标记示例将返回为application/json,因此只显示而非呈现。

正文映射模板text/html尝试与浏览器发送的Accept标头完全匹配。例如,Chrome发送

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

明确!== text/html。也就是说,当我发送上述请求时,会显示正确的响应,但会显示错误的内容类型标题。

我的选项似乎是

  1. 找到一些将默认设置为text/html
  2. 的方法
  3. 找到使通配符或正则表达式工作的方法。例如。 text/*
  4. 我已经尝试了上述但没有用,但我希望我错过了一些东西。

    回应示例

    • 一个用JSON(Accept: application/json

      回应
      {
        "id": "d4ef7d3f-f2..."
      }
      
    • 另一个是标记和一些发送postMessage的JS。 Accept: text/html

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8">
          <title>Example</title>
        </head>
        <body>
          <script>
            parent.postMessage({"id": "d4ef7d3f-f2..."}, "...", window);
          </script>
        </body>
      </html>
      

    API Gateway Swagger的要点

    https://gist.github.com/benswinburne/3a212c936e1d97fe8e17352269d6edb6

1 个答案:

答案 0 :(得分:1)

API网关对内容协商的支持目前有限。

我建议不要直接使用API​​网关提供内容,而是使用瘦客户端层来控制对API网关的调用。这允许完全控制Accept / Content-Type标头等。

作为一个例子,我们通常会看到简单的SPA,通常托管在S3网站上,使用javascript客户端来调用API网关。

或者,您可以覆盖方法响应中Content-Type标头的默认映射。

编辑以解释我是如何根据此答案实施的。

  1. 添加方法回复Content-Type
  2. 添加集成响应标头映射

    Content-Type => integration.response.body.contentType
    
  3. 确保标题参数在您正在使用的所有内容类型的集成请求中映射到正文映射模板中。

  4. 根据以下示例
  5. 更新lambda函数以返回内容类型属性
    exports.handler = (event, context, callback) => {
        var contentType = this.negotiateContentType(event.params.header.Accept);
    
        // abridged
    
        context.done(null, {contentType}); // abridged
    };
    
    exports.negotiateContentType = (header) => {
        var contentType = 'text/html';
    
        if (header.match(/json/ig)) {
            contentType = 'application/json';
        }
    
        return contentType;
    }
    

    如果您不想在响应中使用内容类型,则可以在集成响应中为每种内容类型设置正文映射模板。

    例如

    // All properties
    $input.json('$')
    
    // Custom output
    {
        "myproperty": $input.json('$.myproperty')
    }