使用 BatchGetItem 在请求和响应映射模板中动态获取 DynamoDB table 名称

Get Dynamically DynamoDB table name in request and response mapping template using a BatchGetItem

我正在使用具有文件夹结构的微服务。

Microservice => 
  resolvers -> 
    Media/Image/get-images/request.vtl
    Media/Image/get-images/response.vtl
  templates -> services.yaml

请求映射:

#set($imageIds=$ctx.source.imageIds)
#set($keys=[])
#foreach($imageId in $imageIds)
    #set($key={})
    $util.qr($key.put("id", $util.dynamodb.toString($imageId)))
    $util.qr($keys.add($key))
#end
{
  "version": "2018-05-29",
  "operation": "BatchGetItem",
  "tables" : {
        "MediaImages": {
            "keys": $util.toJson($keys)
        }
  }
}

响应映射:

#set($result=$ctx.result.data.MediaImages)
$util.toJson($result)

Service.yaml

Resources:
  MediaImagesTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: MediaImages
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
        - AttributeName: userId
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5

      GlobalSecondaryIndexes:
        - IndexName: UserImages
          KeySchema:
            - AttributeName: userId
              KeyType: HASH
            - AttributeName: id
              KeyType: RANGE
          Projection:
            ProjectionType: ALL
          ProvisionedThroughput:
            ReadCapacityUnits: 5
            WriteCapacityUnits: 2

  ImageDetailsDataSource:
    Type: AWS::AppSync::DataSource
    Properties:
      Name: ImageDetailsDataSource
      Type: AMAZON_DYNAMODB
      ServiceRoleArn:
        Fn::ImportValue: !Sub "DynamoDB-Role"
      ApiId:
        Fn::ImportValue: !Sub "API-Id"
      DynamoDBConfig:
        TableName: !Ref MediaImagesTable
        AwsRegion: !Ref AWS::Region
        UseCallerCredentials: false

  GetImagesPipelineFunction:
    Type: AWS::AppSync::FunctionConfiguration
    Properties:
      ApiId:
        Fn::ImportValue: !Sub "API-Id"
      Name: GetImagesPipelineFunction
      FunctionVersion: "2018-05-29"
      Description: Function to get the images from dynamo db
      DataSourceName: !GetAtt ImageDetailsDataSource.Name
      RequestMappingTemplateS3Location: ../resolvers/get-images/request.vtl
      ResponseMappingTemplateS3Location: ../resolvers/get-images/response.vtl

我试过了

#set($tableName=$util.dynamodb.getDataSourceTableName())
#set($imageIds=$ctx.source.imageIds)
#set($keys=[])
#foreach($imageId in $imageIds)
    #set($key={})
    $util.qr($key.put("id", $util.dynamodb.toString($imageId)))
    $util.qr($keys.add($key))
#end
{
  "version": "2018-05-29",
  "operation": "BatchGetItem",
  "tables" : {
        "$tableName": {
            "keys": $util.toJson($keys)
        }
  }
}

"error": {
  "message": "1 validation error detected: Value '{$tableName= . 
  [com.amazonaws.dynamodb.v20120810.WriteRequest@1528275d]}' at 
  'requestItems' failed to satisfy constraint: Map keys must satisfy 
  constraint: [Member must have length less than or equal to 255, Member 
  must have length greater than or equal to 3, Member must satisfy regular 
  expression pattern: [a-zA-Z0-9_.-]+] (Service: AmazonDynamoDBv2; Status 
  Code: 400; Error Code: ValidationException; Request ID: 
  464H3LIEPOSA2S8OI34RJ31QLNVV4KQNSO5AEMVJF66Q9ASUAAJG)",
  "type": "DynamoDB:AmazonDynamoDBException"
},

在我的 AppSync 请求映射模板中。我正在执行 BatchGetItem 并对 table 名称进行硬编码。我想将 table 名称动态地获取到我的请求和响应映射模板中。我尝试了映射模板实用程序参考 $util.dynamodb.getDataSourceTableName($dataSourceName) 但没有成功。

我是这样做的:

RequestMappingTemplate: !Sub
  - |
    #set($keys=[])
    #foreach($imageId in $imageIds)
        #set($key={})
        $util.qr($key.put("id", $util.dynamodb.toString($imageId)))
        $util.qr($keys.add($key))
    #end
    {
      "version": "2018-05-29",
      "operation": "BatchGetItem",
      "tables" : {
            "${TableName}": {
                "keys": $util.toJson($keys)
            }
      }
    }
  - { TableName: INSERT YOUR TABLE NAME OR SOME REF HERE }
ResponseMappingTemplate: !Sub
  - |
    #set($result=$ctx.result.data["${TableName}"])
    $util.toJson($result)
  - { TableName: INSERT YOUR TABLE NAME OR SOME REF HERE }

我用!FindInMap [Environments, !Ref Environment, ProjectsTableName]但你也可以用!Ref YourDynamoDBTable代替INSERT YOUR TABLE NAME OR SOME REF HERE