AppSync:管道解析器 #return 空结果

AppSync: pipeline resolver #return null result

我成功地使用管道解析器来保持 parent/child 关系,除非 child 项列表为空并且我 #return 早。

我猜问题出在我的响应映射器和 $ctx.prev$ctx.result 的使用上,但我想不通。

管道看起来像这样:

当我用

调用突变时
{"parentAttribute":"foo", "children": [{"childAttribute": "bar"}]}

我得到了很好的回应,例如:

{
  "data": {
    "createFoo": {
      "parentAttribute": "foo",
      "children": [
        {
          "childAttribute": "bar"
        }
      ]
    }
  }
}

如果没有 children,函数 2 请求映射器会 #return 以避免“TransactWriteItems 必须至少有一个操作”错误。

在这种情况下,我希望对突变做出上述反应,只是 children: [] 相反,我得到:

{
  "data": {
    "createFoo": null
  }
}

数据已正确写入;如果我查询它,我会返回带有 children.

空列表的 parent

如何让这个管道执行,以便它 returns 合并的 parent+child 数据,无论是否填充 child 数组?


详情

架构类似于:

type Foo {
  id: String!
  attr1: String
  bars: [Bar]
}

type Bar {
  id: String!
  attr2: String
}

type Mutation {
  createFoo(foo: Foo): Foo
}

像这样的 dynamodb 表示:

pk sk attr1 attr2
FOO#1 METADATA#FOO#1 Lorem
FOO#1 BAR#1 Ipsum

虽然管道看起来像:

before.vtl

{}

createParent-request.vtl

{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
        "pk" : $util.dynamodb.toDynamoDBJson(...),
        "sk" : $util.dynamodb.toDynamoDBJson(...)
    },
    "attributeValues" : {
        "data" : $util.dynamodb.toDynamoDBJson(...)
    }
}

createParent-response.vtl

#if($ctx.error)
    $utils.error($ctx.error.message, $ctx.error.type)
#end

$utils.toJson($ctx.result)

createChildren-request.vtl

#if($ctx.args.fooInput.children.size() > 0) 
{
    "version": "2018-05-29",
    "operation": "TransactWriteItems",
    "transactItems": [
    #foreach( $child in $ctx.args.fooInput.children )
       {
           "table": "${table}",
           "operation": "UpdateItem",
           "key": {
                "pk" : $util.dynamodb.toDynamoDBJson(...),
                "sk" : $util.dynamodb.toDynamoDBJson(...)
           },
           "update": {
               "expression": "SET #data = :data",
               "expressionNames": {
                   "#data":  "data"
                   
               },
               "expressionValues": {
                    ":data":     
                       $util.dynamodb.toDynamoDBJson(...)
                   
               }
           }
       }

       #if( $foreach.hasNext ),#end
    #end
       
    ]
}
#else
    #return 
#end

createChildren-response.vtl

#if($ctx.error)
    $utils.error($ctx.error.message, $ctx.error.type)
#end

$utils.toJson($ctx.prev.result)

after.vtl

#if($ctx.error)
    $utils.error($ctx.error.message, $ctx.error.type)
#end

$utils.toJson($ctx.prev.result)

我明白了。对于预期的行为,需要 'after' 映射器到 return 必要的 JSON 来填充整体突变响应。在我上面的示例中,after.vtl 需要 return 一个 parent 并且其他都不重要(特别是各个函数响应映射器的结果)。

我最终将 'create parent' 操作的输出放入 ctx.stash,然后 return 在 after.vtl 中输入 ctx.stash,将其他解析器设置为 {}.

请注意,如果您的响应具有子类型(具有自己的解析器)并且您 return 它是稀疏的,AppSync 将调用解析器。在我的示例的上下文中,return parent 没有任何 children 就足够了,然后“获取父项的子项”的正常查询解析器将执行以填充最终响应。