【问题标题】:AWS API gateway body mapping template for dynamodb mapdynamodb 地图的 AWS API 网关主体映射模板
【发布时间】:2017-06-24 00:01:49
【问题描述】:

我试图弄清楚如何通过 AWS 中的 API 网关将动态数据插入到 dynamodb 表中。目前我有一个 dynamodb 表和一个 API 端点设置,可以接受这样的 POST。

POST https://{unique-id}.execute-api.us.east-1.amazonaws.com/notification/events

{
  "reference_number": 99,
  "purchase_date": "1/1/2017"
}

我在 API 网关中设置了一个身体映射模板,以将数据按摩到 dynamodb 中。

{ 
    "TableName": "Events",
    "Item": {
        "reference_number": {
            "N": "$input.path('$.reference_number')"
        },
        "purchase_date": {
            "S": "$input.path('$.purchase_date')"
        }
    }
}

上述工作并保存到表中。

假设我将事件哈希添加到我的 json 中(可以根据事件进行更改)。

{
  "reference_number": 99,
  "purchase_date": "1/1/2017",
  "event": {
     "name": "purchase",
     "items": [1,3,6],
     "info": {
       "currencyID": "USD",
       "countryID": "US"
     }
  }
}

如何使用 API Gateway Body 映射模板语法将事件属性保存到 dynamodb 中的 Map?

{ 
    "TableName": "Events",
    "Item": {
        "reference_number": {
            "N": "$input.path('$.reference_number')"
        },
        "purchase_date": {
            "S": "$input.path('$.purchase_date')"
        },
        "event":{
            "M": "$input.path('$.event')"
        }
    }
}

上面的模板给了我以下错误。 "预期地图或为空"

【问题讨论】:

  • 你试过"event": { "M": "$input.json('$.event')" }吗?
  • 不走运,我得到一个序列化异常。 "__type":"com.amazon.coral.service#SerializationException"

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


【解决方案1】:

对于我的要求(保存输入正文),映射模板是

"rawdata": {
            "M": $input.body
        }

请注意,输入正文没有引号。

并且数据应该是Dynamodb格式,例如

{"username":{"S":"Vishnu"}}

您可以使用 js lib 像 dynamodb-marshaller 将 json 转换为 Dynamodb 格式。希望这会有所帮助。

【讨论】:

    【解决方案2】:

    看来你终于做到了。我认为最好的选择是在 API 和 dynamoDB 之间创建一个简单的 lambda 函数。将映射工作留给 aws-sdk。

    在这种情况下,API 网关中的正文映射模板将像这样简单:

    $input.body
    

    而且功能不会复杂很多。我使用了一个javascript函数:

    var AWS = require("aws-sdk");
    
    var docClient = new AWS.DynamoDB.DocumentClient();
    var tableName = "tableName";
    
    var saveData = function (data) {
    
      var params = {
        TableName: tableName,
        Item: data
      };
    
      docClient.put(params, function (err, data) {
        if (err) {
          console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
        } else {
          console.log("Added item:", JSON.stringify(data, null, 2));
        }
      });
    
    };
    
    exports.handler = function (event) {
      try {
        console.log("Processing event: ", event);
        saveData(event);
      } catch (e) {
        console.error("Processed unsuccessfully", e, e.stack);
      }
    };
    

    http://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/GettingStarted.NodeJs.03.html

    【讨论】:

      【解决方案3】:

      看起来 DynamoDB API 实际上要求“M”属性的值是String -> AttributeValue 的映射。不幸的是,您无法传递原始 JSON。您必须手动映射整个 event 对象才能使 DDB API 满意。

      http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_AttributeValue.html#DDB-Type-AttributeValue-M

      一种可能的解决方法是将event 对象字符串化并将其写入S 类型,但这当然需要读者期待这种行为。

      { 
          "TableName": "Events",
          "Item": {
              "reference_number": {
                  "N": "$input.path('$.reference_number')"
              },
              "purchase_date": {
                  "S": "$input.path('$.purchase_date')"
              },
              "event":{
                  "S": "$util.escapeJavaScript($input.json('$.event'))"
              }
          }
      }
      

      【讨论】:

      • 我将此标记为解决方案,因为它似乎是使用正文映射模板保存事件哈希的唯一方法。然而,我最终使用 lambda 函数将事件保存为地图。谢谢!
      猜你喜欢
      • 2019-07-11
      • 1970-01-01
      • 2018-12-16
      • 1970-01-01
      • 2018-07-31
      • 1970-01-01
      • 2018-12-04
      • 2020-09-28
      • 1970-01-01
      相关资源
      最近更新 更多