我正在使用 dotnet Framework 6.0、CDK v2 和 ApiGatewayV2.Alpha 我正在尝试将消息从 API 网关直接发送到 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; }
}
我需要将请求中的标头之一映射到 SQS 消息的一部分。为了实现这一点,我尝试将此标头映射到消息属性。 其实现方式如下:
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\"}}"
})
});
无论我做什么,都会导致 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 消息中?如果是这样,我该怎么做?
我找到了解决方案,感谢 Reddit 用户!而且一直都是括号。
我将“$request.header.signature”替换为“${request.header.signature}”