1. 2
    Why have a client-side GraphQL cache?
    5m 11s

Why have a client-side GraphQL cache?

Rares Matei
InstructorRares Matei

Share this video with your friends

Send Tweet
Published 10 months ago
Updated 6 months ago

In this lesson, we'll look at how Apollo's client side cache can immediately benefit us, without any special configuration. We'll see how it remembers what data we received from the backend for a specific query and a specific set of variables, and then it pulls those results instantly from the in memory cache, should they be needed again. It minimises network requests and this results in the app being as fast as possible.

Instructor: [0:00] Browsers are good at doing caching for us. If you request the same file twice, it's not going to download it the second time. It's going to pull it from its local cache. Network requests are expensive. Browsers try to do as little of it as possible.

[0:15] Even for GET requests, if you GET a list of notes from an API, some browsers will try to store the results of this in their local cache so that you don't download the same list twice. They do this because it's not hard for browsers to see if something is in their cache already. "Did I already download a file with this name? Did I already make a GET request to /api/notes?"

[0:38] GraphQL queries encourage you to get as specific as possible with the graph, depending on what your component needs. In a different component, I might want all of this plus the image of each note, and also maybe the category ID, and maybe I don't want the label. There are so many ways in which I can request very similar types of data and different components. This makes GraphQL queries very difficult to be cached by browsers.

[1:04] Luckily for us, in the previous lesson, we instantiated Apollo Client with an in-memory cache. Let's see how this can help us. I have here two components -- my list of all the notes, and this slimmer list of notes which I can control via this button. This displays the exact set of notes as I have on the left, except it doesn't show the category for them.

[1:28] If we look at the two components side by side, we see that the slim notes component requests a subset of the data that the full notes list component just requested. It also wants the list of notes, but it just cares about the ID and the content. It doesn't care about the category.

[1:46] Let's filter the network requests to only show the GraphQL queries. I'm going to refresh the page. We'll see a request go out for my list of notes. When I open my slim notes component, there's no new network request, even though all the data has loaded in fine.

[2:03] Even though my two components, technically, made two different queries, Apollo figured out that the data needed for this query was already downloaded as part of this one. It just pulled the data from the local cache, avoiding an extra network request.

[2:17] Let's build something even more useful. Up in my component that controls the app layout, where we have the notes list, I'll add this note category selector here. It's a component I had ready from before. If we look inside it, it's kind of a dumb component. It just displays this list of categories. Whenever the user selects a different one, it dispatches the ID of that category back up to its parent.

[2:45] Let's set up some state to track these categories. I'll track the selected category, I'll name the setter, and I'll initialize everything with the ID of the first category. Whenever the category changes in this component, I'll set it in my state as well. I'll just initialize the drop-down with a default category, and I'll send it as a prop to my notes list.

[3:07] On my notes list, I'll just pull it in from the props. It turns out that my GraphQL server allows me to send a category ID whenever I request a list of notes. If I do that, it's going to return me only the notes of that category.

[3:25] Since I'm now telling Apollo to pass this variable whenever it makes this query, I'll also need to accept it up here as a string. Finally, I'll pass it as an argument to notes. Again, this is how you pass arguments to GraphQL queries. It's nothing Apollo-specific.

[3:43] If we look at the results, we can see that now we get less notes, all of the same selected category. We can also see the variable being passed in through the network request. If I switch the category, Apollo rightfully goes and asks the server for a list of shopping notes. That's why I get this new request.

[4:06] If I switch back to the first category, there's no new network request. Apollo sees that I downloaded Holiday Planning notes at some point in the past, so it pulls that result from the cache. I'm going to refresh the page so that the in-memory cache resets. Then, I'll slow down the network for a bit.

[4:25] If I click on Shopping Notes, you'll notice I'm staring at a blank screen for a while, while the network request resolves. When I click back on the first category, its instant. Shopping, it's instant again, because I have it in the cache. Saved Articles, I have to wait for a bit.

[4:44] Once I see them, they're in the cache. I can even take the network connection offline and everything still works as before.

[4:51] This is what's neat about Apollo Client. Out of the box, without any special configuration, it tracks, and stores, and continuously hydrates your local graph entities in the local cache with new data, as you are using the app. It only asks the server for what it doesn't already have.