为啥 GraphQL 片段在查询中需要 __typename?
Posted
技术标签:
【中文标题】为啥 GraphQL 片段在查询中需要 __typename?【英文标题】:Why do GraphQL fragments need __typename in queries?为什么 GraphQL 片段在查询中需要 __typename? 【发布时间】:2018-01-12 12:51:11 【问题描述】:我找不到或我在错误的地方寻找有关片段如何匹配的任何文档。当我使用香草 Apollo 客户端时,如果我在使用片段时关闭 addTypename
的选项,我会收到警告 heuristic fragment matching going on!
,如果我添加它,它就会消失,但我的响应包含许多 __typename
字段,我没有需要。他们为什么提供帮助?
【问题讨论】:
也许这不能完全满足您的问题,但__typename
似乎是 Apollo 能够匹配其缓存中的片段的唯一踪迹。我认为要解决这个问题,您不需要传递addType: true
- 保持它为假,而是尝试将__typename
添加到您的片段中。
【参考方案1】:
原因是 ApolloClient 和 Relay 一样,使用全局存储在客户端缓存你的数据。
为了为您执行此操作,需要全局 ID。出于某种原因,全局 id 不是人们考虑的问题,事实上,这是人们在切换到 Relay 时一直抱怨的问题。
ApolloClient 对此有一个聪明的解决方案! (如果我错了,Apollo 团队会纠正我)它们允许您定义您的记录如何在商店中键入!默认情况下,它使用 typename 和 id 创建 Relay 建议您创建的那种全局 ID。这就是他们需要类型名称的原因。
由于您在查询中关闭了 typename,Apollo 会做一些聪明的事情来尝试找出类型(以及存储中的键)。这些聪明的东西可能会给你带来麻烦。
如果您想创建自己的全局 id 而不是使用所有这些聪明的东西,您可以像这样指定它:
const cache = new InMemoryCache(
dataIdFromObject: object => object.key || null
);
https://www.apollographql.com/docs/react/advanced/caching.html#normalization
【讨论】:
以上是关于为啥 GraphQL 片段在查询中需要 __typename?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 中发送带有片段的 graphql 查询
GraphQL Relay 自省查询失败:“查询”类型上的未知字段“__type”
你如何在 python 中处理 graphql 查询和片段?