Motivation

Caching is a great way to improve performance, avoid rate limit problems and even save money if you are accessing a paid for API from Apps Script. A big limitation though is that cache entries can only be up to 100k. One way of resolving this is to compress the data, and another is to split the data across multiple cache entries. This library does both.

I’ve provided a number of cache related libraries before on this site, but this one is purpose built and not part of some bigger project – so if you only want Apps Script caching – this is the one you need.

Getting started

You’ll need the bmCachePoint library – id details at the end of this post.

const cacher = new bmCachePoint.Cacher({ 
	cachePoint: CacheService.getUserCache(), 
	expiry: 60*60,
	prefix: 'myapp' 
})
create instance

Where

  • cachePoint : (optional) One of the Apps Script Cache services – if this is null, then no caching is done, but the class methods work but don’t do anything. This will allow you to easily test with and without cache
  • expiry: (optional) default number of seconds for cache entries to live for
  • prefix: (optional) any text –  it will be used to partition entries from each other in cache – you probably won’t need this

Cache keys

You can provide anything as a cache entry key – typically, for an API this will be a url and possibly some options. Any prefix you provided earlier will be added in also to create a unique key for a cache entry

What if data is too big

You don’t need to care about the size of the data you are writing to cache. In fact you can’t even know, since all data is compressed before writing anyway. Just provide data as a string. If the compressed data is still too big for the maximum size the Cache permits it will automatically create multiple cache entries and recombine them when you retrieve the entry from cache

Setting data

Generally speaking you’ll just provide a key and data to the .set method. For api data the key would typically be the url. All data will be compressed and if necessary spread across multiple cache entries.

cacher.set (key, data)
basic cache writing

Advanced setting data

You can also enhance the key by providing an options params – this can be anything. To recover the cache entry data supply the same options and key to the get method. You can also change the default expiry time.

  /**
   * set item to cache
   * @param {string} key the key to identify the data being cached 
   * @param {string} data
   * @param {object} [params] 
   * @param {*} [params.options] any extra stuff to add to the key key
   * @param {expiry} [params.expiry] expiry in seconds to override the default cacher settings
   * @return {string || null} value from cache
   */
  set(key, data, {
    options,
    expiry = this.expiry
  } = {}) {
   ...
  }
   
   // example
   cacher.set ('https://api.com?a=1', 'some data', {
   	user: 'john',
	expiry: 100
   })
   
  
writing data

Getting data

You’ll usually just need the key. If there is no cache entry, you’ll get  a null reponse. Data will be combined from multiple cache entries if required, and decompressed

const data = cacher.get(key)
getting data

Advanced getting data

If you provided an options parameter to enhance they key, you’ll need to specify it here too

   
  /**
   * get item fom cache
   * @param {string} key the key to identify the data being cached 
   * @param {*} [options] any additional options to add to the key
   * @return {string || null} value from cache
   */
  get(key, options ) {
	  ...
  }


   // example
   const data = cacher.get ('https://api.com?a=1',  {
   	user: 'john'
   })
   
advanced getting

Removing entries

You usually don’t need to bother removing items, as they will expire anyway. However, one example of where you might want to is if you know a cache entry is stale.

cacher.remove(key)
removing an entry

Advanced removing data

If you provided an options parameter to enhance they key, you’ll need to specify it here too

  /**
   * remove item fom cache
   * @param {string} key the key to identify the data being cached
   * @param {*} [options] any additional options to add to the key
   */
  remove(key, options) {
	...
  }


   // example
  cacher.remove ('https://api.com?a=1',  {
  	user: 'john'
  })
   
advanced removing

Links

bmCachePoint : 1GOjfvSZL31TxlF61QT1fVNIKnZw9UeqF_2tkPQ5D1n4BBth-yKc6AznH

IDE

Github

Related

SuperFetch

Apps script caching with compression and enhanced size limitations

Motivation Caching is a great way to improve performance, avoid rate limit problems and even save money if you are ...
Read More

Caching across multiple Apps Script and Node projects using a selection of back end platforms

Motivation I've always been interested in ways to get multiple projects in Apps Script sharing data more easily and in ...
Read More

How to prevent unwanted web caching

When you access websites through the browser, caching speeds perceived access since it only actually downloads data for pages and ...
Read More

Database caching

If you are abstracting the database provider, you can move up caching to the handler level. This will mean that ...
Read More
SuperFetch

SuperFetch plugin – Firebase client for Apps Script

Frb is a SuperFetch plugin to easily access a Firebase Real time database. SuperFetch is a proxy for UrlFetchApp with ...
Read More
SuperFetch

SuperFetch plugin – iam – how to authenticate to Cloud Run from Apps Script

SuperFetch is a proxy for UrlFetchApp with additional features - see SuperFetch - a proxy enhancement to Apps Script UrlFetch for ...
Read More
SuperFetch

SuperFetch – a proxy enhancement to Apps Script UrlFetch

I've written a few articles about JavaScript proxying on here, and I'm a big fan. I also use a lot ...
Read More
js proxy

JavaScript proxy, fiddling with Apps Script objects and custom errors

This article is a little more advanced than usual, and we'll cover a number topics in one go. A JavaScript ...
Read More
libraries opportunities

Opportunities and workflows inlining Apps Script libraries

This article will look at some of the opportunities you'll have when you pull in your libraries inline rather than ...
Read More

Inline libraries in an Apps Script project

This piece of work to create inline libraries was both challenging and a lot of fun to produce, and it's ...
Read More