Apollo GraphQL 客户端不会在查询中返回缓存的嵌套类型
Posted
技术标签:
【中文标题】Apollo GraphQL 客户端不会在查询中返回缓存的嵌套类型【英文标题】:Apollo GraphQL client doesn't return cached nested types in a query 【发布时间】:2020-01-13 18:54:59 【问题描述】:我正在执行查询以获取 PowerMeter
详细信息,其中包含名为 Project
的另一种类型。我这样写查询:
query getPowerMeter($powerMeterId: ID!)
powerMeter: powerMeter(powerMeterId: $powerMeterId)
id
name
registry
project
id
name
当我第一次执行查询时,project
成功返回。问题是当我使用相同的参数和默认的fetchPolicy
(cache-first
) 执行后续查询时,project
不再返回。
我该如何解决这个问题?
另外,我调用readFragment
来检查powerMeter
是如何保存在缓存中的,响应显示powerMeter
已保存project
。
const frag = client.readFragment(
fragment: gql`
fragment P on PowerMeter
id
name
registry
project
id
name
`,
id: 'PowerMeter:' + powerMeterId,
);
功率计第一次返回
"powerMeter":
"id":"7168adb4-4198-443e-ab76-db0725be2b18",
"name":"asd123123",
"registry":"as23",
"project":
"id":"41d8e71b-d1e9-41af-af96-5b4ae9e492c1",
"name":"ProjectName",
"__typename":"Project"
,
"__typename":"PowerMeter"
第一次调用功率计后的片段
"id":"7168adb4-4198-443e-ab76-db0725be2b18",
"name":"asd123123",
"registry":"as23",
"project":
"id":"41d8e71b-d1e9-41af-af96-5b4ae9e492c1",
"name":"ProjectName",
"__typename":"Project"
,
"__typename":"PowerMeter"
功率计第二次返回
"powerMeter":
"id":"7168adb4-4198-443e-ab76-db0725be2b18",
"name":"asd123123",
"registry":"as23",
"__typename":"PowerMeter"
第二次调用功率计后的片段
"id":"7168adb4-4198-443e-ab76-db0725be2b18",
"name":"asd123123",
"registry":"as23",
"project":
"id":"41d8e71b-d1e9-41af-af96-5b4ae9e492c1",
"name":"ProjectName",
"__typename":"Project"
,
"__typename":"PowerMeter"
编辑 1:获取查询
下面的代码是我获取数据的方式。我使用的是useApolloClient
,而不是查询挂钩,因为我使用的是 AWS AppSync,它还不支持查询挂钩。
import useApolloClient from '@apollo/react-hooks';
import gql from 'graphql-tag';
import useEffect, useState from 'react';
export const getPowerMeterQuery = gql`
query getPowerMeter($powerMeterId: ID!)
powerMeter: powerMeter(powerMeterId: $powerMeterId)
id
name
registry
project
id
name
`;
export const useGetPowerMeter = (powerMeterId?: string) =>
const client = useApolloClient();
const [state, setState] = useState<
loading: boolean;
powerMeter?: PowerMeter;
error?: string;
>(
loading: true,
);
useEffect(() =>
if (!powerMeterId)
return setState( loading: false );
client
.query<GetPowerMeterQueryResponse, GetPowerMeterQueryVariables>(
query: getPowerMeterQuery,
variables:
powerMeterId,
,
)
.then(( data, errors ) =>
if (errors)
setState( loading: false, error: errors[0].message );
console.log(JSON.stringify(data));
const frag = client.readFragment(
fragment: gql`
fragment P on PowerMeter
id
name
registry
project
id
name
`,
id: 'PowerMeter:' + powerMeterId,
);
console.log(JSON.stringify(frag));
setState(
loading: false,
powerMeter: data.powerMeter,
);
)
.catch(err => setState( loading: false, error: err.message ));
, [powerMeterId]);
return state;
;
编辑 2:获取策略详细信息
当我使用fetchPolice
等于cache-first
或network-only
时,错误仍然存在。当我使用no-cache
时,我没有收到错误消息。
【问题讨论】:
你能分享你获取查询的代码吗?此外,您是否在代码中的其他任何地方手动更新缓存的相关位(即在突变之后)? @DanielRearden 完成!我已经添加了获取查询的方式。不,我此时不会手动更新缓存 我知道它已经过时了,但似乎这个问题仍然出现在 Apollo Client v3.2.3 中。我的同事几天前提出了一个关于此的问题 (github.com/apollographql/apollo-client/issues/9353)。我们注意到了这一点,因为我们使用的是仅限客户端的字段,并且我们的本地解析器正在中断。只是让您知道,以防您仍然感兴趣。 【参考方案1】:我认为这可能是解决方案: https://github.com/apollographql/apollo-client/issues/7050
可能为时已晚,但它可以帮助人们在未来解决这个问题。
在使用 apollo 客户端的 InMemoryCache 时,您似乎需要提供可能类型的列表,以便在使用 InMemoryCache 时正确完成片段匹配。
当联合类型很少且 API 非常稳定且不会经常更改时,您可以手动执行此操作。 或者你自动将这些类型生成到一个 json 文件中,你可以直接在 InMemoryCache 的 possibleTypes 配置中直接使用。
访问this link to the official docs 了解如何操作。
干杯。
【讨论】:
以上是关于Apollo GraphQL 客户端不会在查询中返回缓存的嵌套类型的主要内容,如果未能解决你的问题,请参考以下文章
在 reactJS 中使用动态字段的 Apollo 客户端 graphql 查询
无法将 GraphQL 查询从 Apollo 客户端发送到 Rails GraphQL 后端
vue-apollo:GraphQL 查询仅在使用 <ApolloQuery> 标签时运行。永远不会在脚本代码中工作。 this.$apollo.queries 为空