GraphQL cache mechanism analysis: breaking cache errors
You may have heard of things like "GraphQL does not support caching" or "GraphQL does not care about caching". This is a big problem for many people. But that's not the case. GraphQL's official document mentions a variety of caching technologies, which shows that its development team attaches great importance to caching and its performance advantages.
This article aims to clarify the relationship between GraphQL and cache, and introduce different caching techniques and how to optimize GraphQL queries using cache.
GraphQL automatic caching mechanism
Consider the following query to get a post and its author:
query getPost { post(slug: "working-with-graphql-caching") { id title author { id name avatar } } }
The "secret" to implement GraphQL automatic caching is the __typename
meta field, which is provided by all GraphQL APIs. As the name implies, __typename
returns the type name of the object. This field can even be added manually to an existing query, which most GraphQL clients or CDNs will automatically add, such as urql. The query received by the server may look like this:
query getPost { post(slug: "working-with-graphql-caching") { __typename id title author { __typename id name } } }
The response containing __typename
might look like this:
{ data: { __typename: "Post", id: 5, title: "Working with GraphQL Caching", author: { __typename: "User", id: 1, name: "Jamie Barton" } } }
__typename
is the key to GraphQL cache, because it allows us to cache the results and know that it contains Post ID 5 and User ID 1.
Library such as Apollo and Relay also provide a certain level of built-in caching for automatic caching. Since they already know what is in the cache, they can leverage the cache instead of the remote API to get what the client requests in the query.
Automatic failure cache
Suppose the post author uses editPost
variant to modify the post's title:
mutation { editPost(input: { id: 5, title: "Working with GraphQL Caching" }) { id title } }
Since the GraphQL client automatically adds the __typename
field, the result of this variant immediately tells the cache that Post ID 5 has changed and any cached query results containing the post need to be invalidated:
{ data: { __typename: "Post", id: 5, title: "Working with GraphQL Caching" } }
The next time the user sends the same query, the query will get new data from the source instead of using expired results in the cache.
Normalize GraphQL cache
Many GraphQL clients do not cache the entire query results. Instead, they normalize cached data into two data structures: one associates each object with its data (e.g. Post #5:{…}, User #1:{…}, etc.); the other associates each query with the objects it contains (e.g. getPost:{Post #5, User #1}, etc.).
Please refer to urql's documentation on normalizing caching or Apollo's "Demystifying Cache Normalization" for specific examples and use cases.
GraphQL cache edge case
One of the main edge cases where GraphQL caches cannot handle automatically is adding items to the list. So if createPost
mutation goes through the cache, it doesn't know which specific list to add the item to.
The easiest "workaround" is to query the parent type in the mutation (if it exists). For example, in the following query, we query the community relationship on the post:
query getPost { post(slug: "working-with-graphql-caching") { id title author { id name avatar } # Also query the community of the post community { id name } } }
Then we can also query the community from createPost
variant and invalidate any cached query results containing the community:
mutation createPost { createPost(input: { ... }) { id title # Also query and thus invalidate the community of the post community { id name } } }
While not perfect, typed patterns and __typename
metafields are the keys to making the GraphQL API great for caching.
You might think all of this is a stopgap solution, and GraphQL still doesn't support traditional caching. You can't be wrong. Since GraphQL runs via POST requests, you need to uninstall to the application client and use the "tricks" mentioned above to take advantage of GraphQL's modern browser cache.
However, this approach is not always possible and is not the best way to manage client caches. For more difficult cases, the GraphQL client requires you to manually update the cache, but services like GraphCDN provide a "server-like" caching experience, and also provide a manual clearing API that allows you to do the following for better caching control:
# Purge all occurrences of a specific object mutation { purgeUser(id: [5]) }
# Purge by query name mutation { _purgeQuery(queries: [listUsers, listPosts]) }
# Purge all occurrences of a type mutation { purgeUser }
Now, no matter where you use the GraphCDN endpoint, you no longer need to reimplement the cache policy in all client logic such as mobile, web, etc. Edge caching makes your API very fast and reduces load by sharing caches between users and separating them from each user’s client.
I recently used GraphCDN in a project which helped me handle cache configuration on the client or server, allowing me to continue with my project. For example, I could replace my endpoint with GraphCDN and get the queries complexity (coming soon), analysis and more for free.
So, does GraphQL care about caching? Of course you care! Not only does it provide some built-in automatic caching methods, but many GraphQL libraries provide other ways to implement and manage caching.
Hopefully this article helps you understand the GraphQL caching mechanism, and how to implement it on the client side, and how to leverage CDN to do all the work. My goal is not to convince you to use GraphQL in all your projects, but if you are choosing a query language and caching is an important factor, know that GraphQL is perfectly competent for this task.
The above is the detailed content of Working With GraphQL Caching. For more information, please follow other related articles on the PHP Chinese website!

The React ecosystem offers us a lot of libraries that all are focused on the interaction of drag and drop. We have react-dnd, react-beautiful-dnd,

There have been some wonderfully interconnected things about fast software lately.

I can't say I use background-clip all that often. I'd wager it's hardly ever used in day-to-day CSS work. But I was reminded of it in a post by Stefan Judis,

Animating with requestAnimationFrame should be easy, but if you haven’t read React’s documentation thoroughly then you will probably run into a few things

Perhaps the easiest way to offer that to the user is a link that targets an ID on the element. So like...

Listen, I am no GraphQL expert but I do enjoy working with it. The way it exposes data to me as a front-end developer is pretty cool. It's like a menu of

In this week's roundup, a handy bookmarklet for inspecting typography, using await to tinker with how JavaScript modules import one another, plus Facebook's

I've recently noticed an interesting change on CodePen: on hovering the pens on the homepage, there's a rectangle with rounded corners expanding in the back.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

Zend Studio 13.0.1
Powerful PHP integrated development environment

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

Dreamweaver CS6
Visual web development tools