AppSync:管道解析器 #return 空结果
AppSync: pipeline resolver #return null result
我成功地使用管道解析器来保持 parent/child 关系,除非 child 项列表为空并且我 #return
早。
我猜问题出在我的响应映射器和 $ctx.prev
与 $ctx.result
的使用上,但我想不通。
管道看起来像这样:
- 模板之前:
{}
- 函数 1:
- 请求=
PutItem
parent
- 响应 =
$utils.toJson($ctx.result)
- 功能二:
- 求=
TransactWriteItems
(foreach UpdateItem
)child仁
- 响应 =
$utils.toJson($ctx.prev.result)
- 模板后:
$utils.toJson($ctx.prev.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
就足够了,然后“获取父项的子项”的正常查询解析器将执行以填充最终响应。
我成功地使用管道解析器来保持 parent/child 关系,除非 child 项列表为空并且我 #return
早。
我猜问题出在我的响应映射器和 $ctx.prev
与 $ctx.result
的使用上,但我想不通。
管道看起来像这样:
- 模板之前:
{}
- 函数 1:
- 请求=
PutItem
parent - 响应 =
$utils.toJson($ctx.result)
- 请求=
- 功能二:
- 求=
TransactWriteItems
(foreach UpdateItem
)child仁 - 响应 =
$utils.toJson($ctx.prev.result)
- 求=
- 模板后:
$utils.toJson($ctx.prev.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
就足够了,然后“获取父项的子项”的正常查询解析器将执行以填充最终响应。