taiki-t's diary

React Native, Rails そして雑多な記録: The world is waiting for you to give it a meaning.

Implement a simple caching for Relay Modern.

update - 2017/11/07: Consulting official docs may make you even happier: Add Caching docs by felippepuhle · Pull Request #2121 · facebook/relay · GitHub. It's not merged by now.


Unlike Relay Classic, Relay Modern doesn't come with an automagical caching system out of the box. Instead, it has an utility class to help you implement a cache system.

In this article I'll describe an example implementation of a simple caching. I don't explain much of details but you'd understand if you're already familiar with Relay Modern and I believe you're so as trying to implement a cache.

Code

const {
  Environment,
  Network,
  RecordSource,
  Store,
  QueryResponseCache,
} = require('relay-runtime');

const yourEndPoint = 'https://example.com'

const headers = {
  'content-type' : 'application/json',
}

const cache = new QueryResponseCache({size: 100, ttl: 100000});

function fetchQuery(
  operation,
  variables,
  cacheConfig,
  uploadables,
) {

  const queryId = operation.name

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

  // Handle force option in RefetchOptions
  // See: https://facebook.github.io/relay/docs/pagination-container.html
  // https://facebook.github.io/relay/docs/refetch-container.html
  const forceLoad = cacheConfig && cacheConfig.force

  if (!forceLoad && cachedData) {
    return cachedData;
  }

  if (forceLoad) {
    // clear() means to reset all the cache, not only the entry addressed by specific queryId.
    // See blog comments for more details.
    cache.clear()
  }

  return fetch(`${yourEndPoint}/graphql`, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      query: operation.text, // GraphQL text from input
      variables,
    }),
  }).then(response => {
    const data = response.json();
    // A cache key, queryId in this code, should be unique per query.
    cache.set(queryId, variables, data);
    return data
  });
}

// Create a network layer with the fetch function
export const network = Network.create(fetchQuery);

Related tweets.