Apollo客户端Node.js使用过滤器查询本地状态

时间:2019-10-18 05:06:38

标签: graphql apollo-client

我正在独立的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过滤的本地商店的结果 q1数据返回null的可能原因是什么以及如何解决?:)

1 个答案:

答案 0 :(得分:1)

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