Graphql apollo客户端节点使用筛选器查询本地状态

Graphql apollo客户端节点使用筛选器查询本地状态,graphql,apollo-client,Graphql,Apollo Client,我正在standalone node.js应用程序中使用apollo客户端 客户端(客户端本身没有问题,因此我认为详细的链接,类型定义,解析程序配置不太相关): 查询: export const hubsQuery = gql` query HubsQuery { hubs { id ip port isOnline } }`; export cons

我正在standalone node.js应用程序中使用apollo客户端

客户端(客户端本身没有问题,因此我认为详细的
链接
类型定义
解析程序
配置不太相关):

查询:

export const hubsQuery = gql`
    query HubsQuery {
        hubs {
            id
            ip
            port
            isOnline
        }
    }`;

export const hubsOnlineLocalQuery = gql`
    query HubsQueryLocal {
        hubs(isOnline: true) @client {
            id
            ip
            port
            isOnline
        }
    }`;
    const q0 = await apolloCli.query({query: hubsQuery, fetchPolicy: 'network-only'});
    console.log(q.data);


    const q1 = await apolloCli.query({query: hubsOnlineLocalQuery});
    console.log(r.data)
用法:

export const hubsQuery = gql`
    query HubsQuery {
        hubs {
            id
            ip
            port
            isOnline
        }
    }`;

export const hubsOnlineLocalQuery = gql`
    query HubsQueryLocal {
        hubs(isOnline: true) @client {
            id
            ip
            port
            isOnline
        }
    }`;
    const q0 = await apolloCli.query({query: hubsQuery, fetchPolicy: 'network-only'});
    console.log(q.data);


    const q1 = await apolloCli.query({query: hubsOnlineLocalQuery});
    console.log(r.data)
因此,尽管
q0
成功并包含一个数组,但是从
q1
返回的
数据
null

我的猜测是:

  • 一些我不理解的设计缺陷
  • 本地缓存为每个
    查询唯一地存储数据
  • 我希望
    q1
    返回通过
    isOnline

    q1
    数据返回
    null
    的可能原因是什么,以及如何修复它?:)

    阿波罗使用
    @client
    指令解析字段,首先查找相关的解析程序,如果不存在,则直接在缓存中查找数据

    当查询存储在缓存中时,它们不仅由字段引用,还由传递给这些字段的参数引用。因此像
    hubs(isOnline:true)
    hubs(isOnline:false)
    这样的查询结果将分别存储在缓存中。类似地,
    集线器(isOnline:true)
    集线器
    是单独的查询,并单独存储

    因此,缓存中确实有一些数据,但它实际上与您试图运行的
    集线器(isOnline:true)
    查询没有关联

    即使Apollo在本例中自动从缓存中提取了已经存在的内容,您仍然需要一个自定义解析器,因为您正在尝试实现一些业务逻辑(仅显示联机的集线器),而Apollo无法知道如何仅根据您传入的参数来实现

    在这两种情况下,答案都是为
    hubs
    字段提供自定义解析器。比如:

    const resolvers = {
      Query: {
        hubs: (obj, { isOnline }, { cache }) => {
          const { hubs } = cache.readQuery({ query: hubsQuery })
          return hubs.filter((hub) => hub.isOnline)
        }
      }
    }
    

    您不必共享所有本地解析程序,但回答此问题可能需要专门为
    集线器
    使用的解析程序,因为这是问题最可能出现的地方。也就是说,假设您的解析程序编写正确,我也从未使用过与远程字段共享名称的本地字段。考虑到Apollo解析@client字段的方式,这是可能的,但如果名称冲突导致一些意外行为,我也不会感到惊讶。我根本没有编写解析程序,因为我希望
    q1
    查询本地缓存,正如这里所写的:如果我查询
    hubs@client
    ,而不指定filter
    (isOnline:true)
    ,它确实有效。所以我想既然查询是针对同一个集合运行的,那么它必须在没有解析程序的情况下运行?是的,这是我的猜测,一小时前就这样解决了:)我还没有找到apollo客户端如何准确地搜索缓存-我想它会根据
    \uu typename
    找到相关实体。