确定速度模板请求体属性类型?

时间:2018-03-12 00:53:18

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

我有一个API网关,它使用速度模板作为瘦包装器,允许用户在DynamoDB表上执行CRUD操作。

我试图尽可能动态地编写更新操作,但我遇到的问题是确定来自速度模板中请求体的属性的类型。我正在与之合作:

#set($body = $input.path('$'))
#set($updateExpression = "set")
#set($expressionAttributeNames = "")
#set($expressionAttributeValues = "")
#foreach($attrName in $body.keySet())
    #set($updateExpression = "${updateExpression} #$attrName = :${attrName},")
    #set($expressionAttributeNames = "${expressionAttributeNames}""#${attrName}"":""${attrName}""")
    #set($attrValue = $input.json("$.${attrName}"))

     #if($attrValue.matches("^-?\\d+$"))
         #set($attrValue = """:${attrName}"": { ""N"": ${attrValue}, ")
     #else
        #set($attrValue = """:${attrName}"": { ""S"": """ + $util.escapeJavaScript($attrValue) + """ },")
     #end

    #set($expressionAttributeValues = "${expressionAttributeValues} ${attrValue}")
    #if($foreach.hasNext)
        #set($expressionAttributeNames = "${expressionAttributeNames}, ")
    #end
#end
{
    "TableName": "TABLE",
    "Key": { "id": { "S": "$input.params('id')" } },
    "UpdateExpression": "${updateExpression} updatedOn = :updatedOn",
    "ExpressionAttributeNames": {$expressionAttributeNames},
    "ExpressionAttributeValues": {
        $expressionAttributeValues
        ":updatedOn": { "N": "$context.requestTimeEpoch" }
    }
}

编辑:这是一个示例请求正文:

https://api/v1/endpoint/123

{
    "location": {
        "lat": 42,
        "lon": -71
    },
    "rating": 4
}

这是我得到的当前转变:

{
    "TableName": "users",
    "Key": { "gcn": { "S": "123" } },
    "UpdateExpression": "set #number = :number, #location = :location, updatedOn = :updatedOn",
    "ExpressionAttributeNames": {"#number":"number", "#location":"location"},
    "ExpressionAttributeValues": {
         ":number": { "S": "1" }, ":location": { "S": "{\"lat\":26.89199858375187,\"lon\":75.77141155196833}" },
         ":updatedOn": { "N": "" }
    }
}

我目前只是检查一个值是否为数字...并且它不起作用。

1 个答案:

答案 0 :(得分:0)

在做了一些挖掘后,我达到了我的目的。我有一个用于AWS API Gateway的动态Velocity模板映射,用于更新DynamoDB项目。

到目前为止,它支持字符串,数字,布尔值和字符串转义对象,因为这是我的项目存储它们的方式(它们不可查询)。 ExpressionAttributeNames存在,以防您对属性名称使用保留关键字...就像我为'location'所做的那样。

如果有人有任何改进/改进,请告诉我,这是一个剧本的野兽。

#set($body = $input.path('$'))
#set($updateExpression = "set")
#set($expressionAttributeNames = "")
#set($expressionAttributeValues = "")
#foreach($attrName in $body.keySet())
    #set($updateExpression = "${updateExpression} #$attrName = :${attrName},")
    #set($expressionAttributeNames =     "${expressionAttributeNames}""#${attrName}"":""${attrName}""")
    #set($attrValue = $input.json("$.${attrName}"))

    #if($attrValue.toString().matches("[+-]?\d+"))
        #set($attrValue = """:${attrName}"": { ""N"": ""${attrValue}"" }, ")
    #elseif($attrValue.toString() == "true" || $attrValue.toString() == "false")
        #set($attrValue = """:${attrName}"": { ""BOOL"": ${attrValue} }, ")
    #elseif(($attrValue.toString().startsWith("{") && $attrValue.toString().endsWith("}")) ||
        ($attrValue.toString().startsWith("[") && $attrValue.toString().endsWith("]")) )
        #set($attrValue = """:${attrName}"": { ""S"": """ + $util.escapeJavaScript($attrValue) + """ },")
    #else
        #set($attrValue = """:${attrName}"": { ""S"": " + $attrValue + " },")
    #end

    #set($expressionAttributeValues = "${expressionAttributeValues} ${attrValue}")
    #if($foreach.hasNext)
        #set($expressionAttributeNames = "${expressionAttributeNames}, ")
    #end
#end
{
    "TableName": "", ## Insert your table here.
    "Key": { "gcn": { "S": "$input.params('')" } }, ## Insert your key expression here.
    ## Update below if `updatedOn` is not your audit attribute.
    "UpdateExpression": "${updateExpression} updatedOn = :updatedOn",
    "ExpressionAttributeNames": {$expressionAttributeNames},
    "ExpressionAttributeValues": {
        $expressionAttributeValues
        ":updatedOn": { "N": "$context.requestTimeEpoch.toString()" }
    }
}

示例请求正文:

{
    "firstName": "John",
    "isActive": true,
    "_status": 1
}

示例转换:

{
  "TableName": "users",
  "Key": {
       "id": {
           "S": "1"
        }
  },
  "UpdateExpression": "set #firstName = :firstName, #isActive = :isActive, #_status = :_status, updatedOn = :updatedOn",
  "ExpressionAttributeNames": {
    "#firstName": "firstName",
    "#isActive": "isActive",
    "#_status": "_status"
  },
  "ExpressionAttributeValues": {
    ":firstName": {
      "S": "John"
    },
    ":isActive": {
      "BOOL": true
    },
    ":_status": {
      "N": "1"
    },
    ":updatedOn": {
      "N": "123456789"
    }
  }
}