必须使用API gateway rest api而非http API,因后者不支持requestTemplates和xml透传;需配置contentHandling: CONVERT_TO_TEXT、requestTemplates匹配application/xml,并确保Lambda直接解析原始XML字符串。

CloudFormation 本身不直接支持将 API Gateway 的 requestTemplates 设为 XML 解析模式(比如 application/xml),但可以通过显式配置 IntegrationRequest 的 requestTemplates 和 contentHandling 实现。关键在于:API Gateway v1(REST API)支持 XML,而 v2(HTTP API)**不支持 requestTemplates 或 XML passthrough** —— 必须用 REST API。
必须使用 REST API 而非 HTTP API
HTTP API 在 CloudFormation 中无法指定 requestTemplates,也没有 contentHandling: CONVERT_TO_TEXT 选项,因此无法可靠接收原始 XML 并透传给 Lambda。REST API 才是唯一可行路径。
-
AWS::ApiGateway::RestApi是唯一能配置 XML 处理的资源类型 -
AWS::ApiGatewayV2::Api不接受requestTemplates,且其payloadFormatVersion只支持"1.0"或"2.0",均不解析原始 XML body - 若误用 HTTP API,Lambda 收到的
Event.body会是 base64 编码的字符串,且无明确方式还原原始 XML 结构(尤其含命名空间、DOCTYPE 等)
在 IntegrationRequest 中启用 CONVERT_TO_TEXT 并写 XML 模板
默认情况下,API Gateway 会尝试 jsON 化请求体;要保留原始 XML,必须设置 contentHandling: CONVERT_TO_TEXT,并用 requestTemplates 将 $input.body 直接映射过去。
- 模板中不能用
$input.json('$')(会失败),必须用$input.body -
requestTemplates的 key 必须匹配Content-Type请求头,例如"application/xml" - 务必设置
passthroughBehavior: WHEN_NO_MATCH,否则无匹配模板时会返回 500
{ "Type": "AWS::ApiGateway::Method", "Properties": { "RestApiId": {"Ref": "MyRestApi"}, "ResourceId": {"Ref": "MyResource"}, "HttpMethod": "POST", "AuthorizationType": "NONE", "Integration": { "Type": "AWS_proxy", "IntegrationHttpMethod": "POST", "Uri": {"Fn::Sub": "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyLambda.Arn}/invocations"}, "RequestTemplates": { "application/xml": "$input.body" }, "ContentHandling": "CONVERT_TO_TEXT", "PassthroughBehavior": "WHEN_NO_MATCH" } } }
Lambda 函数需处理 raw String body(不是 JSON)
由于启用了 CONVERT_TO_TEXT,Lambda 的 event.body 是原始 XML 字符串(非 base64,也非 JSON 对象),可直接用标准 XML 解析器处理。
- python 示例中应避免
json.loads(event['body']),改用xml.etree.ElementTree.fromstring(event['body']) - node.js 中可用
new DOMParser().parseFromString(event.body, 'text/xml')或fast-xml-parser - 注意:
event.isBase64Encoded为false,无需Buffer.from(..., 'base64') - 若前端未设
Content-Type: application/xml,API Gateway 会 fallback 到WHEN_NO_MATCH模板(如果没配则报错),所以 header 必须正确发送
部署后测试要点:Header、Encoding、Error Mapping
即使模板写对,实际调用仍可能失败,原因往往不在 CloudFormation 本身,而在请求细节或错误响应配置。
- curl 测试时必须带
-H "Content-Type: application/xml",否则匹配不到模板 - XML 内容若含 UTF-8 特殊字符,需确保请求 body 是 UTF-8 编码,且不额外添加 bom
- 在
MethodResponse和IntegrationResponse中,建议显式定义application/xml的responseTemplates,否则默认返回 JSON 格式错误(如500时) - CloudFormation 不校验 XML 模板语法,拼写错误(如
"applicaiton/xml")会导致请求 500 且日志里只显示 “No template found”
最易被忽略的是:REST API 的 Deployment 资源必须显式依赖 Method 和 Resource,否则更新后 API 不生效;另外,Lambda 执行角色需有 lambda:InvokeFunction 权限,且 API Gateway 需已添加权限(通过 AWS::Lambda::Permission)。这些不是 XML 专属问题,但在调试 XML 流程时常常卡在这几步。