In this lesson, we'll import the RetryLink from Apollo and use it to automatically retry a given query a few times if there's an error. We'll also look at some of the way we can configure the Retry, including whether to jitter the times between retries. Finally, we'll see what links actually are in Apollo, and how it needs a protocol link as the last one in the chain (HttpLink in our case).
Instructor: [0:00] Let's say one of our users is on their phone, and they have a patchy network connection. Suddenly, their network goes offline. The user doesn't know, and they switch the categories. At this point, we immediately show them an error message. A few seconds later, the network comes back, but they are still left staring at this message.
[0:21] Let's tell Apollo to not give up and show the message immediately and, instead, try to keep making the query a few more times, just in case the network comes back up. Back in my top-level index.js file, I'll import the RetryLink from the apollo-link-retry subpackage. I'll then instantiate it. Here, we can customize how we want these retries to happen.
[0:47] I want it to wait two seconds, initially, before attempting to make the query again. After that initial delay, it's going to try and make the query a few more times but at random intervals. Let me set the max time between retries to two seconds, and finally, we want to tell it not to jitter.
[1:07] Jittering means randomizing the times between your retries. You normally don't want to touch this, because if you have, let's say, 1,000 users all using your app at the same time and your server goes down for a few seconds, if you don't jitter, they're all going to keep retrying at the exact same times.
[1:27] Then, when your server comes back up, all those users will hit it at the exact same time, causing it to potentially go down again. Just so we can test this, I'll make it predictable by setting it to false. How do we use this though, and why is it called a link?
[1:43] Apollo allows you to define these links that do something with your query any time it travels through them on its way to the server. Once it gets to the last link in the chain, the request leaves your browser, travels to the server, and then when the server responds, the response goes up back for your chain of length, all the way back to your component.
[2:07] Now, let's imagine we're going to put our RetryLink somewhere in the middle of our link chain. When the request is made again, it goes through the first link, maybe it does something with it. When it gets to the RetryLink, the RetryLink goes, "Hmm, I don't actually care about requests. I only care if there's an error on the response."
[2:27] The RetryLink doesn't do anything now, the request then goes to the third link. It gets to the server, but when it comes back there's an error. Maybe the third link will ignore the error, but when it gets to the RetryLink, it's going to stop the response midway, and it's going to fire it back up again to our server according to our delay logic.
[2:48] Finally, there's one very important rule when building your link chain. The last link, the one just before your request leaves the browser, needs to define where the request should go. Otherwise, Apollo is going to throw an error.
[3:02] We can now send the RetryLink to Apollo Client. If I save this and go back to my app and refresh the page, oh, I'll get an error. That's because this is the only link in my chain right now, and it's not a proper terminating link. It has no idea where it should send the request. Let me import the HTTP link.
[3:25] I'll instantiate it. This is a proper terminating link because it allows us to specify the address of our GraphQL server. This looks familiar. Oh yeah, I've already instantiated my Apollo Client with this. Apollo Client tries to make the initial setup simple for you. If you don't want to bother with links initially, you can just tell it the address of your server directly.
[3:50] Since I have a proper HTTP link now, I can remove this. I'll add my HTTP link after my RetryLink. This is still not going to work. Link, as its singular name implies, expects a single link, not a list of them.
[4:06] I'll import the fromUtility from Apollo Client, and I'll wrap it around my links. This is a special utility that allows you to chain together multiple other links to form together a single superlink, which you can then pass to Apollo.
[4:24] Back in my app, I'll take the network offline, and now, watch these network requests and see what happens here. I'm going to switch the category. We can see the RetryLink tries to make a few more requests. I'll then bring the network online. Finally, we get a successful request, and all of our nodes come back up.
[4:48] Let me clear this. I'll try to do that again. I'll take the network offline, but this time, watch the nodes here. Watch what happens. If I change the category, I see a loading spinner. Apollo still assumes we're trying to load this.
[5:04] It's a nice user experience, but eventually, we see the error message. That's because it already tried one, two, three, four, five times. By default, the RetryLink gives up after five retries, and it lets the error go up to your component.