【问题标题】:AWS Api Gateway connect to SQS with message attributesAWS Api Gateway 使用消息属性连接到 SQS
【发布时间】:2019-03-23 11:06:03
【问题描述】:

我已经按照本教程连接了一个 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

    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 数组进行编码

【问题讨论】:

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


    【解决方案1】:

    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? 的回答中也有更详细的说明

    【讨论】:

    • 感谢您的快速响应,但我得到了您所描述的确切错误,使用您的示例代码属性为空白。转换后的端点请求正文:Action=SendMessage&MessageBody=%7B%7D&MessageAttributes.member.1.Name=source_ip&MessageAttributes.member.1.Value.DataType=String&MessageAttributes.member.1.Value.StringValue=test-invoke-source-ip(只是注释字符限制一个值)
    • 从你发布的内容中不清楚为什么这是一个错误,因为属性 1 显然不是空白的......但你可以用一些引号作弊。这不是正确的引用,但会防止未捕获的值在表单中为空白。将以下内容与上述答案中的内容进行比较,注意添加了两个",看看您是否可以使用它来至少获得成功的响应——&MessageAttributes.member.1.Value.StringValue="$util.urlEncode($context.identity.sourceIp)"##
    • 是的,它显然不是空白的,但我遇到了同样的错误。即使使用硬编码值 Action=SendMessage&MessageBody=%7B%7D&MessageAttributes.member.1.Name=source_ip&MessageAttributes.member.1.Value.DataType=String&MessageAttributes.member.1.Value.StringValue="foo"
    • { "Error": { "Code": "InvalidParameterValue", "Message": "请求必须包含非空消息属性名称。", "Type": "Sender" }, " RequestId": "ded496eb-afc7-5c56-89af-c2a860080ea5" }
    • 我得到与@JohnWebb 相同的错误。我删除了“成员”符号,它工作正常。 &MessageAttributes.1.Name=source_ip## 而不是 &MessageAttributes.member.1.Name=source_ip##
    【解决方案2】:

    我试图使用映射模板从 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
    

    注意:

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

    【讨论】:

      【解决方案3】:

      就我而言,我必须做 API Gateway ---> SNS 并使用 MessageAttributes 进行过滤。这是一个类似的过程。 在这篇文章和其他Is it possible to POST to the SQS url using the post body 中关注 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"
      }
      

      【讨论】:

      • 嗨 Dionis,我正在使用以下模板 ``` Action=Publish &TopicArn=$util.urlEncode("arn:aws:sns:eu-west-2:036220108529:booking-topic-imod -4225") &&Message=$util.urlEncode($input.json('$')) ``` 但是我收到错误 Invalid parameter: TopicArn or TargetArn 原因: no value for required parameter"
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 2020-05-01
      • 2014-11-10
      • 1970-01-01
      • 2017-05-29
      相关资源
      最近更新 更多