And of the author, it fetches the ID, name, and avatar. And there is one magic trick that makes GraphQL caching really great. And that is the underscore, underscore, type name meta field. You can add that to any GraphQL object, in your query, you can add that to any object type, and you will get back the name of the type of the response. So for example, with this query, we would add type name in these two places for the post and also for the author.
When the origin responds with the data, the response will look something like this, with the important piece being that now we have the post data, and we know that the type that was returned there was a post, and the same thing for the author, we got the author data, and we also know that the author is a user. And when we take this response and we store it in our cache locally in the browser, we can now associate that cached query response with those two objects. We can tag it with post with the ID 5 and user with the ID 1.
Okay, that's fine. So we've just taken this query response, we've put it in the cache, we key that by the query that we saw, so by the get post query. And any time we see the same query, we return that same data. Why are these tags relevant? Why do I care that this contains the post with the ID 5 and the user with the ID 1? Well, this is where the magic comes in. GraphQL also has something called mutations, which are essentially just actions. Anything that changes data needs to be a mutation. For example, if we had a mutation that was called edit post, which edits a post, in this case, we're editing the post with the ID 5 and changing its title. Any mutation also has to fetch whatever it changed. So in this case, we're getting back the post. And again, we can do the same thing we did for the query and add the __typename field to the response.
Now, when that response comes back from the origin to our client, the client can look at this response and go, oh, look, we just sent a mutation to the origin. That mutation has come back from the origin, and the data that was returned was the post with the ID 5. Ha! I actually have a CacheQuery response that contains that post with the ID 5. And I can now automatically invalidate that CacheQuery result that contains the stale data of this post. That's amazing, right? And this is what GraphQL clients do under the hood. They do this magic invalidation based on the __typename field and the ID field, and then they combine them to invalidate any stale data that has been changed at the origin.
There's one slight edge case here where the magic kind of ends, which is list invalidation. If you imagine a query that fetches a list of blog posts, in this case, just their ID and title, when we look at the response to this query, it's an array that just contains the one blog post that we have right now, the post with the ID five, how to edge cache GraphQL APIs. Now, a mutation that creates a new post now poses an interesting problem, because of course, the response to this create post mutation will look something like this. It will return an object of a post with the ID six, but of course, our cached query results for the post list doesn't contain the post with the ID six. And that's really annoying, because that means that GraphQL clients can't automatically invalidate lists when new items are created. Kind of frustrating.
Comments