reddit/node-rest-cache

Name: node-rest-cache

Owner: Reddit

Description: An LRU-based caching solution for rest-like data fetching.

Created: 2015-10-30 18:19:58.0

Updated: 2018-03-03 20:45:41.0

Pushed: 2016-03-11 00:36:07.0

Homepage: null

Size: 34

Language: JavaScript

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

restcache

A caching solution for data fetching. Reduces the number of API calls you have

Build Status to make.

What it is

This cache turns a request, such as api.listings.get({ subreddit: 'funny '}) into two caches:

The intent is that you can now run api.listings.get({ id: 1 }), and if the previous query had already populated a listing with id 1, you get an immediate response rather than making another server round-trip.

You can also reset specific instances of objects in the cache, for example, on the event of a patch that edits an object.

How it works

(See ./test for examples)

The constructor, new Cache({ }), takes settings:

The primary function, cache.get, takes a series of arguments:

The cache will generate a key based on a sha1 of the JSON.stringified parameters. It will then look up a list of IDs returned for that key+sha. If it does not exist, it will return a Promise, and attempt to resolve the function passed in with the parameters supplied. It will pass on a promise rejection, or if it is successful, it will:

If the data is in the cache, it will:

Another function, cache.resetData, allows you to reset a single object, a list of objects, or to reset a cache entirely for a given data type. It takes the arguments:

It will attempt to match the object (or, each object in the array), and replace the objects in the cache with the supplied data. Or, if none was passed in, the cache will be cleared for that data type.

If no arguments are provided, it will reset the entire data cache.

You can also use cache.resetRequests() to reset the request cache. It takes up to three optional arguments as well:

If only key is used, the entire cache for that key will be reset; if both, then it will reset for that single reset; if key, parameters, and ids are sent, it will update the ids to the passed-in list.

If no arguments are provided, it will reset the entire request cache.

Caveats
A Sample
tion loggedOut (params) {
turn !params.token;


cache = new cache.get({
les: {
loggedOut: function(params) {
  return !params.token;
},

faultRequestCacheConfig: {
cache: {
  max: 50, //50 items
  length: function(n) { return n.length }, //how length is determined
  dispose: function(key, n) { n.close() }, // optional handling on disposal
  maxAge: 1000 * 60 * 5, // 5 minutes
},
rules: [ loggedOut ]

taTypes:
listings: {
  idProperty: '_id',
  cache: {
    max: 75,
    maxAge: 1000 * 60 * 3
  }
},
comments: {
  cache: false, // don't cache comments
}



tion formatListings(data) {
turn { listings: data };


tion unFormatListings(data) {
turn data.listings;


tion getData(url) {
turn new Promise(function(resolve, reject) {
superagent
  .get(url)
  .then(function(err, res) {
    if(err) { return reject(err); }

    resolve({
      headers: res.headers,
      body: res.body
    });
  });
;


apiParams = { subreddit: 'funny' };

se `api.listings.get.name` as the key, and use the default config.
listings = cache.get(api.listings.get, [apiParams], {
rmat: formatListings
format: unformatListings


ings.then(
nction(data) { /*...*/ },
nction(error) { /*...*/ }


se a custom key and config. Because it has a different key, it will force a
ache refresh of the listing in question, even though it may already be in
he listing cache.

apiParams = { subreddit: 'funny' };
apiParameters = { _id: 1 };
key = 'edit-listing-cache';
listing = cache.get(
            key,
            api.listings.get,
            [apiParams],
            {
              format: formatListings,
              unformat: unformatListings
            }
          );

ing.then(
nction(listings) { /*...*/ },
nction(error) { /*...*/ }


eset an object in the cache that was updated
listings.patch(params).then(function(res) {
che.resetData('listings', res.listing);


bliterate the cache
e.resetData('listings');

oad a single object
apiParams = { id: 17 };
e.getById('listings', apiParams.id, api.listings.get, [apiParams], {
rmat: formatListings,
format: unformatListings


elete an object, then fix the caches
listings.delete(17).then(function(res) {
 Remove the object from the data cache
che.deleteData('listings', 17);

 Optionally force-reset the request if you know the params ahead of time
che.resetRequests(api.listings.get, [], { listings: [15,16,18] });

Other Notes for Your Careful Consideration

This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.