如何从Python Lambda返回GraphQL Union到AWS AppSync?

8

是否可以从Python Lambda使用GraphQL Union 做出响应?如何实现?看起来是可能的,但我无法完成它。

我包括了一个__typename属性,但大多数情况下我会遇到这个错误:

{'errorType': 'BadRequestException', 
 'message': "Could not determine the exact type of MealMix. Missing __typename key on value.'"}

MealMix 是我的联合类型,其模式如下:

type Meal { name: String }
type OtherMeal { name: String }
union MealMix = Meal | OtherMeal
type Query {
    GetMealMix(identity_id: ID!, date: AWSDate!): [MealMix]
}

查询是:

        query test_query {
            GetMealMix(identity_id: "this", date: "2020-11-20") {
                ... on Meal {name}
                ... on OtherMeal {name}
            }
        }

我从Lambda返回的是:

return [{' __typename': 'Meal',
         'name': 'Kiwifruit, Zespri Gold, Raw'},
        {' __typename': 'OtherMeal',
         'name': 'The meal at the end of the universe'}]

响应模板是默认的:$util.toJson($ctx.result)

我的搜索结果似乎表明我只需要包含__typename属性,但没有明确的Python示例。首先我问一下,是否白费力气(意思是这个功能未实现且永远不会生效),其次,如果它可用,具体怎么做?


我已经断断续续地研究了这个问题几天了。只是确认一下 - 您的 lambda 记录了正确的返回值,但 HTTP 响应返回了错误请求? - pygeek
公平的问题。我手头没有它来进行双重检查,但答案将是“是”:lambda返回了如下所示的字典列表...返回语句是剪切/粘贴的,而httpresponse.content是顶部的错误类型字典。你有成功过吗? - John Mee
我发布了一个带有一些建议的答案——我认为选项2更有可能是你的答案。哦,我不确定identity_id: "this"是什么,但它可能会缓存你的结果并导致奇怪的问题,即使模拟响应也要考虑每次传递唯一的内容。 - pygeek
你可能想要查看appsync-tools模块中的typify。免责声明,我是作者。如果在结果中添加__typename,则返回联合将正常工作,如果您的查询/突变使用“... on <type>”语句。 - OneLiner
2个回答

0

问题

一方面,我发现有些例子中需要在查询中包含__typename,就像你提到的那样。 另一方面,这也很有趣,因为AWS文档没有提到在查询中包含__typename,但确实提到了接口的使用,所以我想这可能是让事情正常工作的关键,即所有类型都扩展相同的接口。

解决方案

选项1

尝试在MealOtherMeal片段中包含__typename(你提到过在查询中使用__typename,但不确定你把它放在哪里)。

示例

query test_query {
            GetMealMix(date: "2020-11-20") {
                ... on Meal {
                    __typename
                    name
                }
                ... on OtherMeal {
                    __typename                    
                    name
                }
            }
        }

选项2

联合类型中包含的所有类型都使用相同的接口,正如您分享的文档中的一个部分所示,标题为“类型解析示例”

示例

interface MealInterface { name: String }
type Meal implements MealInterface { name: String }
type OtherMeal implements MealInterface { name: String }

笔记

硬编码响应

您返回了一个硬编码响应,但我不确定在 AWS Lambda 上处理 GQL 响应是否需要附加元数据。尝试记录响应以确定是否包含 __typename。如果未包含 __typename,请考虑将 typename 添加到 id 中,并使用您分享的 AWS 文档中推荐的转换。

#foreach ($result in $context.result)
    ## Extract type name from the id field.
    #set( $typeName = $result.id.split("-")[0] )
    #set( $ignore = $result.put("__typename", $typeName))
#end
$util.toJson($context.result)

identity_id

"identity_id" 参数中的 "this" 可能会由于 GraphQL 处理 ID 类型的方式而导致缓存问题(请参见:https://graphql.org/learn/schema/#scalar-types)。

参考资料

AWS 上的 GraphQL __typename 查询示例:https://github.com/LambdaSharp/AppSync-Challenge GraphQL 标量类型:https://graphql.org/learn/schema/#scalar-types


抱歉,伙计,我还没有机会回去尝试这个。我会处理的。通过阅读赏金说明,看起来如果我跳过所有正确的步骤,我仍然可以授予它,如果成功的话,我会这样做。 - John Mee
@JohnMee 或许赏金的宽限期已经过期了。不过,如果你成功了,请告诉我。 - pygeek
我目前正在构建一个Appsync应用程序,该应用程序从同一查询中的联合返回多个不同类型。我可以说,我的所有测试都表明联合中的所有类型都需要实现相同的接口。我们使用appsync-tools中的typify插入类型名称,然后在查询中使用“... on Foo”语法。 - OneLiner

-1
你可以按照下面的方式编写代码。 这应该对你有用。
schema {
    query: Query
}

type Query {
    GetMealMix(identity_id: ID!, date: AWSDate!): [MealMix]
}

union MealMix = Meal | OtherMeal

type Meal {
    name: String
}

type OtherMeal {
    name: String
}

query {
    GetMealMix(identity_id: "this", date: "2020-11-20") {
        ... on Meal {name}
        ... on OtherMeal {name}
    }
}

您可以参考以下网址: GraphQL 中的接口和联合

你好。你自己能否从lambda返回一个混合类型的列表?这个“答案”似乎只是问题的重新格式化。尽管如此,还是很不错的尝试 :-/ - John Mee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接