首页 > 解决方案 > AppSync:管道解析器#return null 结果

问题描述

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

我猜问题出在我的响应映射器和$ctx.prevvs的使用上,$ctx.result但我无法弄清楚。

管道如下所示:

当我用

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

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

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

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

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

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

数据已正确写入;如果我查询它,我会用空的子列表返回父级。

如何让这个管道执行,以便它返回组合的父+子数据,无论子数组是否填充?


细节

架构类似于:

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

type Bar {
  id: String!
  attr2: String
}

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

像这样的 dynamodb 表示:

PK sk 属性1 属性2
食品#1 元数据#FOO#1 洛雷姆
食品#1 酒吧#1 伊普苏姆

虽然管道看起来像:

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)

标签: aws-appsync

解决方案


我想到了。对于预期的行为,需要“后”映射器来返回必要的 JSON 以填充整个突变响应。在我上面的示例中,after.vtl需要返回 aparent而没有其他问题(特别是单个函数响应映射器的结果)。

我最终将“创建父级”操作的输出放入ctx.stash然后返回ctx.stashafter.vtl将其他解析器设置为{}.

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


推荐阅读