1. 19
    Implement cache redirect policies to avoid slow network requests for new queries
    3m 27s

Implement cache redirect policies to avoid slow network requests for new queries

Rares Matei
InstructorRares Matei

Share this video with your friends

Send Tweet
Published 9 months ago
Updated 6 months ago

Apollo, by default, does not assume what a given query might return. Anytime you invoke a query that wasn't invoked before, or it has been invoked, but not with the same variables, Apollo always asks the backend for the results. In some cases, however, we know that a given query can re-use a specific object or list of objects already in the cache.

Instructor: [0:00] Let me slow down the network. Our notes list has loaded and has already been cached. This note specifically that I'm going to click on, it's already in the cache.

[0:09] When I try to open it, I see a spinner. If I look in the Network tab, I see a brand-new network request that returned information that should have already existed in the cache, like the note's content and its ID, and so on. Why is this happening? Why isn't Apollo just loading this note directly from the cache instantly?

[0:28] Whenever a component makes any one of these queries, like notes or note, Apollo simply cannot assume what the backend will return. Whenever you make a query that hasn't been made before or has been made but you're passing new variables to it, Apollo always goes to the server. It is simply the safest behavior to ensure it doesn't give you bad data.

[0:50] You'll notice that if I now click on the second note, it makes a request and I get a spinner. If I click on this one, it makes another request and it has a spinner. Then, if I make a query that's just been made before, such as clicking on the second note, it now knows what that query returns, so it can pull the result from the cache instantly.

[1:10] We know that when a component makes a query for a note with ID 1, it will always result in a reference to a cached object with ID note 1. Same for a query using the variable ID 2. It will result in a reference to an object in the cache with ID note 2.

[1:28] We can afford to tweak the Apollo defaults a bit. I'll define a new TypePolicy for the note query with the read function, and I will return an object that contains a ref property to my first note, but how do we dynamically set this ID?

[1:43] If you remember, my read function accepts an existing cached value and some helpers. To get the queried note ID, on the helpers, we'll find the args that were passed to the note query. From those args, I can get the ID variable so we can use this to build our reference.

[2:01] Back in the browser, I'll make sure the network is slowed down. If I now click on the first note, it loads instantly. We see no new request has been made. I can even take the network offline. If I now click on the second note, it loads. Same for the third note. Everything works.

[2:19] While this works fine, we mentioned earlier how the __ reference notation in Apollo is private to their library and might change in the future. Instead of manually creating this object, I'll use the two-reference helper and pass it the minimum amount of info that's required to create a reference to a cached object, the note ID, and its typename.

[2:44] This just generates the same object we had before, but it's good practice to rely on Apollo helpers rather than building our own. If I go back to the browser, slow down the network, I can see it still works. If I take it offline, I can still load all the other notes with good user experience.

[3:01] In summary, because we know that a note query will always result in a reference to a note and the cache, we just overrode the Apollo default. Instead of making a network call, we created a cache redirect policy that gets the note ID passed as an arg to the query and creates a reference to an existing note in the cache, so that it's returned instantly to the caller without having to make an extra network request.