First of all, we need to understand how requests caching work in Relay. Whenever we want to reach out the server Relay uses its network helper which does all the calls to the API. The relay network takes a function(resolver) and it must implement the API call, that’s where all the magic happens. Let’s say it looks like this:

The idea is to save response data to a cache store by query name and variables. Query name is what is defined in a query, for example:

graphql`

query MyQueryExample($country: String!) {

getUsersByCountry(country: $country) {

name

age

}

}

`

Query name of this query would be MyQueryExample. I decided to use query name instead of hash(this one is being created by relay-compiler during converting graphql queries into relay’s ones) because it’s verbose. Later on, you can easily clean cache of this query just using the name. The variables argument is also mandatory because you might have two queries with the same name but with different variables, for example:

// this is a pseudocode, usually it is done by passing args to relay // query renderer

const getRuUsers = relay.fetch({ country: 'Russia' });

const getEuUsers = relay.fetch({ country: 'Europe' });

The first one fetches users from Russia and the second one from Europe. If we used only query name as a key then relay would overwrite the first response by the second one because relay would not be able to distinguish this two queries only by name. One more time: use query name(or hash) and variables to build a key for cache store.

cache.set(queryID, variables, data);

Now how it works, before we force relay to send a request to the server we try to get the response for this query from the cache

const cachedData = cache.get(queryID, variables);

and if it’s there we just return it and if there’s no cache for such query we just send it to the server. Once we send a request to the server we need to save its response in the cache using the same name and variables. That’s it basically.

Relay will keep the cache for the time defined in ttl argument, in my case it’s 60 * 5 * 1000 ms which equals to 5 minutes.