首页 > 解决方案 > apollo 客户端 nodejs 使用过滤器查询本地状态

问题描述

我在独立的 node.js 应用程序中使用 apollo 客户端。

客户端(客户端本身没有问题,所以我认为详细linktypeDefsresolvers配置不是那么相关):

apolloCli = new ApolloClient({
    link,
    cache: new InMemoryCache(),
    typeDefs,
    resolvers
});

查询:

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是成功的并且包含一个数组,data但从返回的q1null.

我的猜测是:

  1. 一些我不明白的设计缺陷
  2. 本地缓存为每个query.

我希望q1从本地存储返回结果,该结果由数据返回isOnline 的可能原因是什么以及如何修复它过滤?:)q1null

标签: graphqlapollo-client

解决方案


Apollo 使用@client指令解析字段,首先查找相关的解析器,如果不存在,则直接在缓存中查找数据。

当查询存储在缓存中时,它们不仅被字段引用,还被传递给这些字段的参数引用。所以一个查询的结果就像hubs(isOnline: true)和一样hubs(isOnline: false)会单独存储在缓存中。同样hubs(isOnline: true),和hubs是单独的查询并单独存储。

因此,您在缓存中确实有一些数据,但它实际上与hubs(isOnline: true)您尝试运行的查询无关。

即使在这种情况下 Apollo 确实自动从缓存中的内容中提取,您仍然需要一个自定义解析器,因为您正在尝试实现一些业务逻辑(仅显示在线的集线器)并且 Apollo 无法知道如何仅根据您传入的参数来实现它。

无论哪种情况,答案都是为该hubs字段提供自定义解析器。就像是:

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

推荐阅读