You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将ApiGatewayV2请求头映射到SQS消息?

API Gateway HTTP API 映射请求头到SQS消息属性报错解决

我使用.NET 6.0、CDK v2和ApiGatewayV2.Alpha,尝试将API Gateway的消息直接发送到SQS队列,因该版本无现成集成,自行实现了HttpSqsSendIntegration。现在需要将请求中的一个Header映射为SQS消息属性,按如下方式配置后始终出现400错误,错误信息为:

"Unable to resolve property MessageAttributes from source {"Signature":{"DataType":"String","StringValue":"$request.header.signature"}}. Please make sure that the request to API Gateway contains all the necessary fields specified in request parameters"

请问是否可以将请求头映射到SQS消息?若可以,该如何实现?

自定义集成代码

using System.Diagnostics.CodeAnalysis;
using Amazon.CDK.AWS.Apigatewayv2.Alpha;
using Amazon.CDK.AWS.IAM;
using Amazon.CDK.AWS.SQS;
using Constructs;

namespace Infrastructure;

public class HttpSqsSendIntegration : HttpRouteIntegration
{
    private readonly Queue _queue;
    private readonly HttpSqsSendIntegrationProps? _props;
    private readonly Role _role;

    public HttpSqsSendIntegration(Construct scope, string id, Queue queue, HttpSqsSendIntegrationProps? props = null) : base(id)
    {
        ArgumentNullException.ThrowIfNull(queue);
        ArgumentNullException.ThrowIfNull(scope);

        _queue = queue;
        _props = props;
        _role = new Role(scope, "HTTP-API-SQS-Role", new RoleProps
        {
            AssumedBy = new ServicePrincipal("apigateway.amazonaws.com"),
            InlinePolicies = new Dictionary<string, PolicyDocument>
            {
                {
                    "sqs-send", new PolicyDocument(new PolicyDocumentProps
                    {
                        Statements =
                        [
                            new PolicyStatement(new PolicyStatementProps
                            {
                                Actions =
                                [
                                    "sqs:SendMessage"
                                ],
                                Resources =
                                [
                                    queue.QueueArn
                                ],
                                Effect = Effect.ALLOW
                            })
                        ]
                    })
                }
            }
        });
    }

    public override IHttpRouteIntegrationConfig Bind(IHttpRouteIntegrationBindOptions options)
    {
        var paramMapping = new ParameterMapping()
            .Custom("QueueUrl", _queue.QueueUrl)
            .Custom("MessageBody", _props?.MessageBody ?? "$request.body");

        if (!string.IsNullOrWhiteSpace(_props?.MessageAttributes))
        {
            paramMapping.Custom("MessageAttributes", _props.MessageAttributes);
        }

        return new HttpRouteIntegrationConfig
        {
            Type = HttpIntegrationType.AWS_PROXY,
            Subtype = HttpIntegrationSubtype.SQS_SEND_MESSAGE,
            PayloadFormatVersion = PayloadFormatVersion.VERSION_1_0,
            ParameterMapping = paramMapping,
            Credentials = IntegrationCredentials.FromRole(_role)
        };
    }
}

public class HttpSqsSendIntegrationProps
{
    public string? MessageBody { get; init; }

    public string? MessageAttributes { get; init; }

    public string[] Headers { get; init; }
}

路由配置代码

var route = new HttpRoute(this, "HttpRoute",
            new HttpRouteProps
            {
                HttpApi = Framework.ApiGateway.Api,
                RouteKey = HttpRouteKey.With("/webhooks/{platform}/{webhook}", HttpMethod.POST),
                Integration = new HttpSqsSendIntegration(this, "SqsRouteIntegration", queue, new HttpSqsSendIntegrationProps
                {
                    MessageAttributes = "{\"Signature\":{\"DataType\":\"String\",\"StringValue\":\"$request.header.signature\"}}"
                })
            });

解决方案

可以将请求头映射到SQS消息属性,问题出在参数映射的格式解析逻辑上:API Gateway的参数映射不支持直接传递预转义的JSON字符串作为Custom参数值,需改用Velocity模板语法来动态构建符合要求的MessageAttributes结构。

正确实现方式

  1. 修改集成类的参数映射逻辑
    去掉预转义的JSON格式,直接用Velocity模板语法构建消息属性字符串,确保变量$request.header.signature能被API Gateway正确解析:

    public override IHttpRouteIntegrationConfig Bind(IHttpRouteIntegrationBindOptions options)
    {
        var paramMapping = new ParameterMapping()
            .Custom("QueueUrl", _queue.QueueUrl)
            .Custom("MessageBody", _props?.MessageBody ?? "$request.body");
    
        // 直接使用Velocity模板构建MessageAttributes,避免预转义
        var messageAttrs = "{\"Signature\":{\"DataType\":\"String\",\"StringValue\":\"$request.header.signature\"}}";
        paramMapping.Custom("MessageAttributes", messageAttrs);
    
        return new HttpRouteIntegrationConfig
        {
            Type = HttpIntegrationType.AWS_PROXY,
            Subtype = HttpIntegrationSubtype.SQS_SEND_MESSAGE,
            PayloadFormatVersion = PayloadFormatVersion.VERSION_1_0,
            ParameterMapping = paramMapping,
            Credentials = IntegrationCredentials.FromRole(_role)
        };
    }
    
  2. 路由配置保持不变
    原路由配置中传递的MessageAttributes值格式是正确的,无需修改,确保请求中确实携带了signature请求头即可。

  3. 关键注意事项

    • 必须确保请求携带signature请求头,否则API Gateway会因变量未定义抛出解析错误
    • 保留PayloadFormatVersion.VERSION_1_0,这是SQS集成要求的负载格式版本
    • 确认IAM角色已正确配置sqs:SendMessage权限

内容的提问来源于stack exchange,提问作者Tom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 08:30:33