2 votes

Mise en cache d'une requête GraphQL avec plusieurs identifiants à l'aide d'Apollo

Nous utilisons le client apollo dans une application web et nous cherchons des moyens d'améliorer l'utilisation du cache.

Nous avons une requête qui prend un tableau d'ids comme paramètre ; un exemple de requête avec des ids foo y bar ressemblerait à ceci :

query routes {
  routes(routeNames: ["foo", "bar"]) {
    items {
      name
      route
      defaults
    }
  }
}

La configuration du cache ressemble à ceci :

export const cacheRedirects = {
  Query: {
    routes: (_: any, args: RoutesArgs, { getCacheKey }: Resolver<'name'>): Array<CacheKey> =>
      args.routeNames.map(name => getCacheKey({ __typename: 'Route', name })),
  },
};

export const dataIdFromObject = (object: QueryResult): ?string => {
  switch (object.__typename) {
    case 'Route':
      return `${object.__typename}:${object.name}`;
    default: return defaultDataIdFromObject(object);
  }
};

export function newCache(): InMemoryCache {
  return new InMemoryCache({ dataIdFromObject, cacheRedirects });
}

Maintenant, lorsque nous utilisons la requête à plusieurs endroits dans notre client, nous aimerions récupérer uniquement les données pour les noms de route qui ne sont pas mis en cache via le réseau et récupérer le reste via le cache.

Le problème se résume donc à ceci : Lorsqu'on a une requête qui met en cache les résultats pour routeNames: ["foo", "bar"] et plus tard, une autre requête arrive demandant les routes pour routeNames: ["bar", "baz"] nous aimerions prendre le résultat correspondant à "bar" du cache et envoyer une requête pour routeNames: ["baz"] .

Je ne sais pas si et comment cela peut être fait avec Apollo parce que, contrairement à la Exemple de cacheRedirect Ici, nous avons affaire à plusieurs identifiants plutôt qu'à un seul.


Maintenant, si nous ne pouvons pas mettre en cache chaque élément du tableau, la prochaine meilleure chose que nous pourrions faire serait de transformer les identifiants en clés de cache communes de sorte que ["foo", "bar"] y ["bar", "foo"] finissent par utiliser la même clé de cache, mais ["foo", "baz"] en utiliserait un autre.

Bien sûr, l'idéal serait de ne récupérer que "baz" comme l'élément manquant dans notre scénario.

1voto

Mikael Lirbank Points 51

Une idée est de vérifier le cache local avant d'effectuer la requête proprement dite, et de supprimer simplement les ID (noms de route) déjà dans le cache de la liste des ID (noms de route) à interroger.

Pour vérifier le cache sans toucher au réseau, utilisez readQuery() o readFragment() .

La documentation est ici :

https://www.apollographql.com/docs/react/advanced/caching.html#readquery https://www.apollographql.com/docs/react/advanced/caching.html#readfragment

MISE À JOUR : Vous pouvez également définir la valeur de l'option fetchPolicy a cache-only dans les options de votre requête.

https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-config-options-fetchPolicy

MISE À JOUR 2 : Une bonne façon d'intégrer les vérifications pour qu'elles soient exécutées pour chaque requête peut être un intergiciel client personnalisé, qui sera exécuté sur chaque requête avant d'appeler le serveur.

https://www.apollographql.com/docs/react/advanced/network-layer.html#linkMiddleware

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X