AWS API 网关 body 映射通配符
AWS API Gateway body map wildcard
我在 AWS API 上设置了一个 API 网关,它使用内容协商提供两种获取某些数据的方法。
我的问题是因为 default Content-Type
header appears to be application/json
,下面的标记示例返回为 application/json
,因此只是显示而不是渲染。
body 映射模板 text/html
尝试对浏览器发送的 Accept
header 进行精确匹配。例如,Chrome 发送
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
其中清楚!== text/html
。也就是说,当我发送上述请求时,显示了正确的响应,但显示了错误的内容类型 header。
我的选择似乎是
- 找到一些将默认值设置为
text/html
的方法
- 找到使通配符或正则表达式起作用的方法。例如。
text/*
我已尝试上述方法无济于事,但我希望我遗漏了什么。
响应示例
一个回复 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
API 目前对内容协商的网关支持有限。
我建议不要直接使用 API 网关提供内容,而是使用瘦客户端层来控制对 API 网关的调用。这允许完全控制 Accept/Content-Type header 等。
例如,我们通常会看到简单的 SPA,通常托管在 S3 站点上,带有 javascript 客户端调用 API 网关。
或者,您可以在方法响应中覆盖 Content-Type header 的默认映射。
编辑以解释我是如何根据这个答案实现它的。
- 添加方法响应
Content-Type
添加集成响应header映射
Content-Type => integration.response.body.contentType
确保 header 参数映射到您正在使用的所有内容类型的集成请求中的 body 映射模板中。
- 根据以下示例将 lambda 函数更新为 return 内容类型 属性
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;
}
如果您不想在响应中使用该内容类型,您可以在集成响应中为每个内容类型设置一个 body 映射模板。
例如
// All properties
$input.json('$')
// Custom output
{
"myproperty": $input.json('$.myproperty')
}
我在 AWS API 上设置了一个 API 网关,它使用内容协商提供两种获取某些数据的方法。
我的问题是因为 default Content-Type
header appears to be application/json
,下面的标记示例返回为 application/json
,因此只是显示而不是渲染。
body 映射模板 text/html
尝试对浏览器发送的 Accept
header 进行精确匹配。例如,Chrome 发送
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
其中清楚!== text/html
。也就是说,当我发送上述请求时,显示了正确的响应,但显示了错误的内容类型 header。
我的选择似乎是
- 找到一些将默认值设置为
text/html
的方法
- 找到使通配符或正则表达式起作用的方法。例如。
text/*
我已尝试上述方法无济于事,但我希望我遗漏了什么。
响应示例
一个回复 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
API 目前对内容协商的网关支持有限。
我建议不要直接使用 API 网关提供内容,而是使用瘦客户端层来控制对 API 网关的调用。这允许完全控制 Accept/Content-Type header 等。
例如,我们通常会看到简单的 SPA,通常托管在 S3 站点上,带有 javascript 客户端调用 API 网关。
或者,您可以在方法响应中覆盖 Content-Type header 的默认映射。
编辑以解释我是如何根据这个答案实现它的。
- 添加方法响应
Content-Type
添加集成响应header映射
Content-Type => integration.response.body.contentType
确保 header 参数映射到您正在使用的所有内容类型的集成请求中的 body 映射模板中。
- 根据以下示例将 lambda 函数更新为 return 内容类型 属性
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;
}
如果您不想在响应中使用该内容类型,您可以在集成响应中为每个内容类型设置一个 body 映射模板。
例如
// All properties
$input.json('$')
// Custom output
{
"myproperty": $input.json('$.myproperty')
}