API 网关中 AWS Firehose PutRecordBatch 的映射模板应该是什么样的?

What should the mapping template look like for AWS Firehose PutRecordBatch in API Gateway?

我已经使用 PutRecord 成功设置了一个 API 与 AWS API 集成的 Kinesis Firehose 网关(https://aws.mannem.me/?p=1152 - 注意:它说不安全,但我仍然点击通过,因为我需要它)。

我正在尝试为 PutRecordBatch 设置一个 API(实质上允许一次写入多个记录)但我一直收到

{ "__type": "SerializationException" }

根据数小时的研究,当传入的 API 调用格式与集成请求中记录的映射模板不匹配时,API 网关会抛出该错误。我正在努力弄清楚如何修复我的映射模板。

这是我的映射模板:

{
    "StreamName": "$input.path('DeliveryStreamName')",
    "Records": [
           #foreach($elem in $input.path('$.Records'))
              {
                "Data": "$util.base64Encode($elem.Data)",
              }#if($foreach.hasNext),#end
            #end
        ]
}

这是我要发送的测试数据:

{
    "DeliveryStreamName": "test",
    "Records": [{
        "Data": "SampleDataStringToFirehose"
    },
    {
        "Data": "SampleDataStringToFirehose2"
    }]
}

太蠢了,但是映射模板有一个错误:

末尾有一个额外的逗号

"Data": "$util.base64Encode($elem.Data)",

这是导致问题的原因。以下是正确的版本:

{
    "DeliveryStreamName": "$input.path('$.DeliveryStreamName')",
    "Records": [
           #foreach($elem in $input.path('$.Records'))
              {
                "Data": "$util.base64Encode($elem.Data)"
              }#if($foreach.hasNext),#end
            #end
        ]
}

你的例子对我帮助很大,所以我想补充它,以防其他人运行进入我的特定场景。

在我的例子中,我需要发送一个 JSON 对象,而不是一个简单的字符串,类似于:

{
   "DeliveryStreamName": "test",
   "Records": [{
       "Data": {"foo": "bar", "count": 321}
    },
    {
       "Data": {"foo1": "bar1", "count": 10}
    }]
}

在这种情况下,我在你的例子中使用模板时发生的情况是对象以非JSON格式存储,不适合进一步分析。

通过简单调整模板,您可以存储格式正确的 JSON 对象:

{
    "StreamName": "$input.path('DeliveryStreamName')",
    "Records": [
           #foreach($elem in $input.path('$.Records'))
              {
                #set($jsonPath = "$.Records[$foreach.index].Data")
                "Data": "$util.base64Encode($input.json($jsonPath))"
              }#if($foreach.hasNext),#end
            #end
     ]
}