клиент apollo nodejs запрашивает локальное состояние с фильтрами - PullRequest
1 голос
/ 18 октября 2019

Я использую клиент apollo в автономном приложении node.js.

client (нет проблем с самим клиентом, поэтому я думаю, что подробно link, typeDefs, resolvers конфиги не так актуальны):

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, возвращаемое из q1, равно null.

Я предполагаю:

  1. некоторый недостаток дизайна, который я не понимаю
  2. Локальный кеш хранит данные уникально для каждого query.

Я ожидаю, что q1 вернет результаты из локального хранилища, отфильтрованные по isOnline В чем может быть причина q1 данных, возвращающих null и как это исправить?:)

1 Ответ

1 голос
/ 18 октября 2019

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