Analyse du mécanisme de cache GraphQL: rupture des erreurs de cache
Vous avez peut-être entendu parler de choses comme "GraphQL ne prend pas en charge la mise en cache" ou "GraphQL ne se soucie pas de la mise en cache". C'est un gros problème pour beaucoup de gens. Mais ce n'est pas le cas. Le document officiel de GraphQL mentionne une variété de technologies de mise en cache, qui montrent que son équipe de développement attache une grande importance à la mise en cache et à ses avantages de performance.
Cet article vise à clarifier la relation entre GraphQL et Cache, et introduire différentes techniques de mise en cache et comment optimiser les requêtes GraphQL à l'aide du cache.
Considérez la requête suivante pour obtenir un message et son auteur:
requête getPost { Post (slug: "Working-with-graphql-caching") { identifiant titre auteur { identifiant nom avatar } } }
Le "secret" pour implémenter la mise en cache automatique GraphQL est le champ Meta __typename
, qui est fourni par toutes les API GraphQL. Comme le nom l'indique, __typename
renvoie le nom de type de l'objet. Ce champ peut même être ajouté manuellement à une requête existante, que la plupart des clients ou CDN GraphQL ajouteront automatiquement, comme URQL. La requête reçue par le serveur peut ressembler à ceci:
requête getPost { Post (slug: "Working-with-graphql-caching") { __Typename identifiant titre auteur { __Typename identifiant nom } } }
La réponse contenant __typename
pourrait ressembler à ceci:
{ données: { __TyPename: "Post", ID: 5, Titre: "Travailler avec GraphQL Caching", auteur: { __TyPename: "utilisateur", ID: 1, Nom: "Jamie Barton" } } }
__typename
est la clé du cache GraphQL, car il nous permet de mettre en cache les résultats et de savoir qu'il contient le post ID 5 et l'ID utilisateur 1.
La bibliothèque telle qu'Apollo et le relais fournissent également un certain niveau de mise en cache intégrée pour la mise en cache automatique. Puisqu'ils savent déjà ce qu'il y a dans le cache, ils peuvent tirer parti du cache au lieu de l'API distante pour obtenir ce que le client demande dans la requête.
Supposons que l'auteur du post utilise la variante editPost
pour modifier le titre du post:
mutation { editPost (entrée: {id: 5, titre: "Travailler avec GraphQL Caching"}) { identifiant titre } }
Étant donné que le client GraphQL ajoute automatiquement le champ __typename
, le résultat de cette variante indique immédiatement au cache que le post ID 5 a changé et que les résultats de la requête en cache contenant le message doivent être invalidés:
{ données: { __TyPename: "Post", ID: 5, Titre: "Travailler avec GraphQL Caching" } }
La prochaine fois que l'utilisateur envoie la même requête, la requête obtiendra de nouvelles données de la source au lieu d'utiliser des résultats expirés dans le cache.
De nombreux clients GraphQL ne mettent pas en cache tous les résultats de la requête. Au lieu de cela, ils normalisent les données mises en cache en deux structures de données: l'une associe chaque objet à ses données (par exemple Post # 5: {…}, l'utilisateur # 1: {…}, etc.);
Veuillez vous référer à la documentation de l'URQL sur la normalisation de la mise en cache ou la «normalisation du cache démystifiant d'Apollo pour des exemples spécifiques et des cas d'utilisation.
L'un des principaux cas de bord où les caches GraphQL ne peuvent pas gérer automatiquement consiste à ajouter des éléments à la liste. Donc, si createPost
passe par le cache, il ne sait pas à quelle liste spécifique ajouter l'élément.
La «solution de contournement» la plus simple consiste à interroger le type de parent dans la mutation (s'il existe). Par exemple, dans la requête suivante, nous interrogeons la relation communautaire sur le post:
requête getPost { Post (slug: "Working-with-graphql-caching") { identifiant titre auteur { identifiant nom avatar } # Interroge également la communauté du message communauté { identifiant nom } } }
Ensuite, nous pouvons également interroger la communauté à partir de createPost
et invalider tous les résultats de la requête en cache contenant la communauté:
mutation createost { CreatePost (entrée: {...}) { identifiant titre # Interrogez également et invalide donc la communauté du poste communauté { identifiant nom } } }
Bien qu'ils ne soient pas parfaits, les motifs dactylographiés et les métafields __typename
sont les clés pour rendre l'API GraphQL idéal pour la mise en cache.
Vous pourriez penser que tout cela est une solution Stopgap, et GraphQL ne prend toujours pas en charge la mise en cache traditionnelle. Vous ne pouvez pas vous tromper. Étant donné que GraphQL s'exécute via des demandes de poste, vous devez désinstaller le client de l'application et utiliser les "astuces" mentionnées ci-dessus pour profiter du cache de navigateur moderne de GraphQL.
Cependant, cette approche n'est pas toujours possible et n'est pas le meilleur moyen de gérer les caches des clients. Pour des cas plus difficiles, le client GraphQL vous oblige à mettre à jour manuellement le cache, mais des services comme GraphCDN offrent une expérience de mise en cache "comme un serveur", et offrent également une API de compensation manuelle qui vous permet de procéder à faire ce qui suit pour un meilleur contrôle de mise en cache:
# Purge toutes les occurrences d'un objet spécifique mutation { purgeuser (id: [5]) }
# Purge par nom de requête mutation { _purgeQuery (requêtes: [listusrs, listPosts]) }
# Purge toutes les occurrences d'un type mutation { purgeuser }
Maintenant, peu importe où vous utilisez le point de terminaison GraphCDN, vous n'avez plus besoin de réimplémenter la stratégie de cache dans toute la logique client telle que mobile, Web, etc. Edge Caching rend votre API très rapidement et réduit la charge en partageant des caches entre les utilisateurs et en les séparant du client de chaque utilisateur.
J'ai récemment utilisé GraphCDN dans un projet qui m'a aidé à gérer la configuration du cache sur le client ou le serveur, me permettant de poursuivre mon projet. Par exemple, je pourrais remplacer mon point de terminaison par GraphCDN et obtenir la complexité des requêtes (à venir bientôt), une analyse et plus encore gratuitement.
Alors, GraphQL se soucie-t-il de la mise en cache? Bien sûr, vous vous souciez! Non seulement il fournit des méthodes de mise en cache automatique intégrées, mais de nombreuses bibliothèques GraphQL fournissent d'autres moyens d'implémenter et de gérer la mise en cache.
J'espère que cet article vous aidera à comprendre le mécanisme de mise en cache GraphQL et comment l'implémenter du côté client, et comment exploiter CDN pour faire tout le travail. Mon objectif n'est pas de vous convaincre d'utiliser GraphQL dans tous vos projets, mais si vous choisissez un langage de requête et que la mise en cache est un facteur important, sachez que GraphQL est parfaitement compétent pour cette tâche.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!