AWS Api Gateway使用消息属性连接到SQS

时间:2018-10-18 15:22:18

标签: amazon-web-services aws-api-gateway amazon-sqs

通过遵循本教程,我已经连接了Api Gateway方法以推送到SQS队列。

https://dzone.com/articles/creating-aws-service-proxy-for-amazon-sqs

这一切都很好,但是我想使用一些路径参数将一些消息属性添加到我的消息中,但是我无法使其正常工作。

这是本教程中的当前映射模板。

Action=SendMessage&MessageBody=$util.urlEncode($util.escapeJavaScript($input.json('$')))

我试图保留'application / x-www-form-urlencoded'格式,并通过将MessageAttributes更改为(现在使用静态值)来添加MessageAttributes

    Action=SendMessage&MessageBody=$util.urlEncode($util.escapeJavaScript($input.json('$')))
&MessageAttribute[0][Name]=foo&MessageAttribute[0][Type]=String&MessageAttribute[0][Value]=bar

但是我又得到了这个错误

{
  "Error": {
    "Code": "MalformedQueryString",
    "Message": "Keys may not contain [",
    "Type": "Sender"
  },
  "RequestId": "ea121e6e-ca37-5d14-b92b-4a2c6fedf403"
}

如何在不使用'['

的情况下对MessageAttribues数组进行编码

3 个答案:

答案 0 :(得分:2)

SQS API Reference并没有完全清楚,实际上似乎与该服务真正希望看到的内容不一致。在网络上,它使用.member.N.表示法,并且N是基于1而不是基于0的。另外,MessageAttributes是复数。

期望的格式如下:

&MessageAttributes.member.1.Name=source_ip##
&MessageAttributes.member.1.Value.DataType=String##
&MessageAttributes.member.1.Value.StringValue=$util.urlEncode($context.identity.sourceIp)##
&MessageAttributes.member.2.Name=user_agent##
&MessageAttributes.member.2.Value.DataType=String##
&MessageAttributes.member.2.Value.StringValue=$util.urlEncode($context.identity.userAgent)##
&MessageAttributes.member.3.Name=stage##
&MessageAttributes.member.3.Value.DataType=String##
&MessageAttributes.member.3.Value.StringValue=$util.urlEncode($context.stage)##

##用于提高可读性。构建Web表单时,映射模板中不能包含换行符,因为它们最终会以表单本身结尾,并且##告诉VTL,从此处到行尾的所有内容都应为忽略,包括行尾的换行符。否则,嵌入的换行符会使表单构造不正确。

还请注意,API不允许将这些值留空,因此,如果有可能不存在任何属性,则您将需要额外的逻辑来进行测试并将其替换为其他属性,因为索引号(iirc)必须是连续的。

为什么我们使用主体映射模板为API Gateway + SQS构建Web表单,以及有关如何配置它的更多信息,请参见Is it possible to POST to the SQS URL using the POST body?

答案 1 :(得分:1)

就我而言,我必须执行API Gateway ---> SNS并使用MessageAttributes进行过滤。这是一个类似的过程。 在本文和其他{@ 3}之后,关注了Michael-sqlbot解决方案之后 我正在共享对我有用的映射模板和POST正文有效负载。

映射模板:

Action=Publish##
&TopicArn=$util.urlEncode('arn:aws:sns:us-west-2:111111:TOPIC_NAME')##
&Message=$util.urlEncode($input.json('$.Message'))##
&Subject=$util.urlEncode($input.json('$.Subject'))##
&MessageAttributes.member.1.Name=hostName##
&MessageAttributes.member.1.Value.DataType=String##
&MessageAttributes.member.1.Value.StringValue=$util.escapeJavaScript($input.json('$.HostNameValue'))##

请注意

&MessageAttributes.member.1.Name=hostName##

由于它是KEY,因此已进行硬编码,如果将其映射为POST负载,则会收到错误消息属性名称无效(它与“”相同)。

这个

&MessageAttributes.member.1.Value.StringValue=$util.escapeJavaScript($input.json('$.HostNameValue'))##

也将按原样发送HostNameValue。由于我们使用urlEncode,当它碰到SNS时会看起来像这样,因此您的过滤器将无法工作。

  "MessageAttributes": {
    "hostName": {
      "Type": "String",
      "Value": "\"your.host.name\""
    }

POST正文有效载荷:

{
    "Subject": "YOLO",
    "Message": "Bla",
    "HostNameValue": "your.host.name"
}

答案 2 :(得分:1)

我试图使用映射模板从AWS API网关传递SQS MessageAttributes。 我最终跟踪了来自aws cli的等效请求,以使用MessageAttributes向SQS提交消息。它涉及到设置本地https代理并查看aws cli生成的原始http POST请求。根据请求,我可以将工作映射模板放在一起:

Action=SendMessage&MessageBody=message+with+attribute&MessageAttribute.1.Name=somename&MessageAttribute.1.Value.DataType=String&MessageAttribute.1.Value.StringValue=somevalue

这是我用于测试的原始aws cli命令:

aws sqs send-message --queue-url "queue/url"  --message-body "message with attribute" --message-attributes '{"somename" : { "DataType":"String", "StringValue":"somevalue"}}' --no-verify-ssl

aws文档还显示格式https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html#API_SendMessage_Examples

样品申请

https://sqs.us-east-2.amazonaws.com/123456789012/MyQueue/
?Action=SendMessage
&MessageBody=This+is+a+test+message
&MessageAttribute.1.Name=my_attribute_name_1
&MessageAttribute.1.Value.StringValue=my_attribute_value_1
&MessageAttribute.1.Value.DataType=String
&MessageAttribute.2.Name=my_attribute_name_2
&MessageAttribute.2.Value.StringValue=my_attribute_value_2
&MessageAttribute.2.Value.DataType=String
&Expires=2020-05-05T22%3A52%3A43PST
&Version=2012-11-05
&AUTHPARAMS

注意:

  • 它是 MessageAttribute ,而不是 MessageAttributes
  • 传递地图参数,您不需要.member.