Graphql Apollo客户端-长查询加短查询与一个查询来管理所有查询相比,哪一个更有意义?
我的用户查询越来越长,我正在考虑将其分为两个查询,一个是Graphql Apollo客户端-长查询加短查询与一个查询来管理所有查询相比,哪一个更有意义?,graphql,apollo,react-apollo,apollo-client,Graphql,Apollo,React Apollo,Apollo Client,我的用户查询越来越长,我正在考虑将其分为两个查询,一个是ME\u查询,其中包含最常用的参数,如userType、userName、userID,另一个是user\u查询,以包含用户所需的所有参数,但是,USER\u查询仅在用户设置和付款页面中需要,而ME\u查询几乎在每个组件中都使用,因为我需要ACL的userType无处不在 但我不确定将它们分成两个查询是否是一个好主意,因为它们都缓存在内存中各自的空间中,所以将它们分开意味着内存中的两个位置,虽然查询很长,但会很长,但只在内存中保留一个位置,
ME\u查询
,其中包含最常用的参数,如userType、userName、userID,另一个是user\u查询
,以包含用户所需的所有参数,但是,USER\u查询
仅在用户设置和付款页面中需要,而ME\u查询
几乎在每个组件中都使用,因为我需要ACL的userType
无处不在
但我不确定将它们分成两个查询是否是一个好主意,因为它们都缓存在内存中各自的空间中,所以将它们分开意味着内存中的两个位置,虽然查询很长,但会很长,但只在内存中保留一个位置,并且在发生突变后更新也会更容易
所以问题是,我是否也需要ME\u查询
,还是用户登录后已经运行过一次的USER\u查询
就足够了
以下是两个问题:
export const USER_QUERY = gql`
query {
user {
uid
avatar
isAdmin
projectCount
sessions
providers
payments // is a long object itself
coupon
credits
email
userName
userType
createdAt
hasPassword
companyName
vatNumber
addressLine1
addressLine2
country
companySize
}
}
`;
简短回答:查询拆分当然有好处,但它在于用户体验的改善,并且只有通过正确配置InMemoryCache才能实现
Apollo中的查询结果已规范化:
InMemoryCache会在将数据保存到存储之前对其进行规范化,方法是将结果拆分为单个对象,为每个对象创建唯一标识符,并将这些对象存储在平坦的数据结构中。默认情况下,InMemoryCache将尝试使用常见的id和_id主键作为唯一标识符(如果它们与对象上的__typename一起存在)
如果您在用户查询中没有看到这种行为,可能是因为您的id字段被称为uid
,而不是id
或\u id
。您需要实现自定义dataIdFromObject函数:
在您的问题中,正确配置缓存意味着两件事:
- 获取具有相同缓存键的对象的查询将合并其结果
- 返回与现有缓存键匹配的对象的突变将自动更新该对象
这意味着您可以拆分用户
查询,请求最少数量的字段以最初加载页面,并延迟请求其余字段,直到用户导航到需要这些字段的页面。您甚至可以使用来提前获取第二个查询
此外,如果您有更新用户的变异,只要变异返回具有匹配缓存键的对象(即,在本例中,它包括guid
),它将自动更新该对象的缓存。在这种情况下,无需重新提取查询或手动更新存储——Apollo将为您处理所有这些
旁注:缓存中的对象列表不受上述影响。如果一个突变导致需要从列表中添加或删除某些内容,阿波罗无法推断哪些列表受到影响。在这种情况下,你会
查询拆分可以让你的应用程序更快,改善用户体验,但不会影响内存量,也不会因为Apollo中缓存的工作方式而影响突变后更新缓存的难度
export const ME_QUERY = gql`
query {
user {
uid
avatar
isAdmin
email
userName
userType
createdAt
}
}
`;
import { InMemoryCache, defaultDataIdFromObject } from 'apollo-cache-inmemory'
const cache = new InMemoryCache({
dataIdFromObject: object => {
switch (object.__typename) {
// or whatever your user type is called
case 'User': return `${object.__typename}:${object.uid}`
// other types here that don't have an id or _id
default: return defaultDataIdFromObject(object)
}
}
})