在 AWS AppSync 查询中返回嵌套 JSON

Posted

技术标签:

【中文标题】在 AWS AppSync 查询中返回嵌套 JSON【英文标题】:Return nested JSON in AWS AppSync query 【发布时间】:2019-01-19 01:11:14 【问题描述】:

总的来说,我对 AppSync(和 GraphQL)还很陌生,但是在将解析器连接到我们的 DynamoDB 表时遇到了一个奇怪的问题。具体来说,我们有一个嵌套的 Map 结构,用于我们任意构建的项目属性之一(其复杂性和形式取决于父项目的类型)——有点像这样:

"item" : 
    "name": "something",
    "country": "somewhere",
    "data" : 
        "nest-level-1a": 
            "attr1a" : "foo",
            "attr1b" : "bar",
            "nest-level-2" : 
                "attr2a": "something else",
                "attr2b": [
                    "some list element",
                    "and another, for good measure"
                ]
            
        
    ,
    "cardType": "someType"

我们附带的 GraphQL 类型如下:

type Item 
    name: String!
    country: String!
    cardType: String!
    data: AWSJSON!  ## note: it was originally String!

当我们查询项目时,我们会得到以下响应:


    "data": 
        "genericItemQuery": 
            "name": "info/en/usa/bra/visa",
            "country": "USA:BRA",
            "cardType": "visa",
            "data": "\"tourist\":\"reqs\":\"sourceURL\":\"https://travel.state.gov/content/passports/en/country/brazil.html\",\"visaFree\":false,\"type\":\"eVisa required\",\"stayLimit\":\"30 days from date of entry\",\"pages\":\"One page per stamp required\""

问题是我们似乎无法让 Item.data 字段解析器返回 JSON 对象(即使我们在通用查询解析器之上附加了一个单独的字段级解析器)。它总是返回一个字符串,奇怪的是,如果我们将预期的字段类型更改为字符串!,响应将用= 替换数据中的所有:。我们已经用我们的响应解析器尝试了所有方法,包括像How return JSON object from DynamoDB with appsync? 这样的建议,但我们完全被困在这一点上。

在上述帖子中的建议均无效后,我们当前的查询响应解析器已恢复为标准响应:

## 'Before' response mapping template on genericItemQuery query; same result as the 'After' listed below **
#set($result = $ctx.result)
#set($result.data = $util.parseJson($ctx.result.data))
$util.toJson($result)

## 'After' response mapping template **
$util.toJson($ctx.result)

我们试图避免需要在data 中为每个嵌套级别包含支持类型的情况(因为它会根据父项类型而变化,并且在我给出的示例中,它可以有三层或四层),我们认为将模式类型更改为 AWSJSON! 就可以了。不过,我开始担心没有办法绕过重建我们的基本模式。任何相反的建议都会有所帮助!

附:我在 CloudWatch 日志中注意到,在 context.result.data 响应字段下存在适当的 JSON 响应,但不知何故有以下 transformedTemplate (再次,考虑到我们没有应用任何映射模板,除了将结果转换为有效的 JSON):

"arn": ...
"transformedTemplate": "data=tourist=reqs=sourceURL=https://travel.state.gov/content/passports/en/country/brazil.html, visaFree=false, type=eVisa required, stayLimit=30 days from date of entry, pages=One page per stamp required, resIds=USA:BRA, cardType=visa, id=info/en/usa/bra/visa",
"context": ...

抱歉这个冗长的问题,但我很难过。

【问题讨论】:

您是否在 Item.data 仍然是 String! 时创建了该项目? 我遇到了这个确切的问题,你有什么发现吗? 不要期望在 AWSJSON 类型的 GraphQL 响应中看到 JSON 对象。 GraphQL 将只为您在模式中声明的类型返回 JSON 对象。对于 AWSJSON 类型,它将返回一个包含转义 JSON 的字符串。 【参考方案1】:

AWSJSON 是一种 JSON 字符串类型,因此您将始终返回一个字符串值(这是您的类型定义必须遵守的内容)。

【讨论】:

【参考方案2】:

您可以尝试为包含所有可能字段的数据字段创建一个类型,然后将字段解析为对应于父类型的字段,或者您可以尝试实现graphQL interfaces

【讨论】:

以上是关于在 AWS AppSync 查询中返回嵌套 JSON的主要内容,如果未能解决你的问题,请参考以下文章

如何通过查询在 AWS AppSync 中的嵌套字段上进行筛选

AWS AppSync Lambda 解析器获取查询返回类型

即使禁用离线,AWS AppSync 查询也会返回缓存响应

AWS AppSync:如何通过 DynamoDB 返回有效的 JSON

使用 AWS Amplify/AppSync 的嵌套 GraphQL 突变

如何使用订阅和 AWS AppSync 高效同步 Apollo 的缓存