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)
    }
  }
})