Apollo Client多dogs查询的Mutation自动重取最优策略咨询
问题描述
现有以下几个GraphQL查询:
gql` query GetDogs { dogs { id breed } } `;
gql` query GetDogsInfo { dogs { id name color createdAt } } `;
gql` query GetDogsShort { dogs { id name image } } `;
所有查询都获取dogs字段,但各自请求的子字段不同。执行mutation操作后需要重新获取所有这些dogs相关的查询,目前是通过指定重取列表实现,但复杂应用中新增dogs查询时需要手动更新这个列表,现寻求最优解决方案,要求不可合并为单个查询。
解决方案
1. 字段依赖触发自动重取(以Apollo Client为例)
这是最省心的方案,不需要维护任何查询列表。利用客户端缓存的字段依赖机制,当mutation修改dogs相关数据后,直接更新缓存中dogs字段的引用,让所有依赖该字段的查询自动触发重取:
client.mutate({ mutation: UpdateDogMutation, update(cache) { // 修改dogs字段的缓存引用,触发所有依赖该字段的查询更新 cache.modify({ fields: { dogs(existingDogs = []) { // 返回新数组引用,让客户端识别为数据变更 return [...existingDogs]; } } }); } });
只要查询用到了dogs字段,不管子字段是什么,都会自动被重取,新增查询时完全不用额外操作。
2. 查询标签自动匹配
给所有dogs相关查询统一添加自定义注释标签,写个工具函数自动筛选这些查询进行重取:
首先定义查询时加标签:
gql` # @dogsQuery query GetDogs { dogs { id breed } } `;
然后写工具函数筛选并重取:
// 筛选所有带@dogsQuery标签的查询 function getDogRelatedQueries(client) { return Object.keys(client.cache.data.data).filter(key => { const queryMeta = client.cache.data.metadata[key]; return queryMeta?.query.loc.source.body.includes('# @dogsQuery'); }); } // mutation执行后调用 client.mutate({ mutation: UpdateDogMutation, update(cache) { const dogQueries = getDogRelatedQueries(client); dogQueries.forEach(queryKey => { client.refetchQueries({ include: [queryKey] }); }); } });
新增dogs查询时,只要加上# @dogsQuery标签,就会被自动纳入重取范围,不用手动更新列表。
3. 集中管理查询分组
把所有dogs相关查询放到同一个模块里,统一导出查询列表:
创建dogQueries.js模块:
import { gql } from '@apollo/client'; export const GET_DOGS = gql` query GetDogs { dogs { id breed } } `; export const GET_DOGS_INFO = gql` query GetDogsInfo { dogs { id name color createdAt } } `; export const GET_DOGS_SHORT = gql` query GetDogsShort { dogs { id name image } } `; // 统一导出所有dogs查询 export const ALL_DOG_QUERIES = [GET_DOGS, GET_DOGS_INFO, GET_DOGS_SHORT];
mutation时直接用这个列表:
import { ALL_DOG_QUERIES } from './dogQueries'; client.mutate({ mutation: UpdateDogMutation, refetchQueries: { include: ALL_DOG_QUERIES } });
新增查询时,只需要在这个模块里添加新查询并加入ALL_DOG_QUERIES数组,把维护工作集中到一处,避免分散修改出错。
内容的提问来源于stack exchange,提问作者A.A
相关产品推荐
相关产品推荐

