aws-appsync - AppSync:管道解析器#return null 结果
问题描述
我成功地使用管道解析器来保持父/子关系,除非子项列表为空并且我#return
很早。
我猜问题出在我的响应映射器和$ctx.prev
vs的使用上,$ctx.result
但我无法弄清楚。
管道如下所示:
- 模板之前:
{}
- 功能一:
- 请求 =
PutItem
父级 - 回应 =
$utils.toJson($ctx.result)
- 请求 =
- 功能二:
- 请求 =
TransactWriteItems
(foreach UpdateItem
) 孩子们 - 回应 =
$utils.toJson($ctx.prev.result)
- 请求 =
- 后模板:
$utils.toJson($ctx.prev.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)
解决方案
我想到了。对于预期的行为,需要“后”映射器来返回必要的 JSON 以填充整个突变响应。在我上面的示例中,after.vtl
需要返回 aparent
而没有其他问题(特别是单个函数响应映射器的结果)。
我最终将“创建父级”操作的输出放入ctx.stash
然后返回ctx.stash
,after.vtl
将其他解析器设置为{}
.
请注意,如果您的响应具有子类型(具有自己的解析器)并且您返回它是稀疏的,AppSync 将调用解析器。在我的示例的上下文中,返回parent
没有任何内容就足够了children
,然后“获取父母的孩子”的正常查询解析器将执行以填充最终响应。
推荐阅读
- php - 我们如何获得动态下拉菜单以根据先前的下拉菜单显示特定选项,并能够随机化输出?
- java - 用vue和spring下载excel文件
- mysql - 尝试从链接服务器检索数据 - 在“等待初始通信数据包”时丢失与 MySQL 服务器的连接,系统错误:10060”
- python-3.x - 无法在标签上显示变量
- javascript - React - 如何构建一个简单的按钮应用程序?
- tfs - 如何从 TFS WorkItemTrackingHttpClient QueryByWiqlAsync 分页结果
- java - 找不到适合 jdbc:postgresql - 可执行的 java jar 的驱动程序
- java - EventSourceHandler 被错误的事件触发?
- javascript - 为什么 for..of 不能处理这个规范函数
- javascript - 刷新饼图后,切片值被清除