Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Distributed HTTP caching backed by memcached and implemented via middleware
JavaScript
branch: master

README.md

Cacher

It does the hard work so you don't have to!

Travis

What is it?

HTTP Caching implemented as express middleware, with pluggable backends for support for a variety of caching servers (memcached, redis, etc)

Features

  • Set expiry times per-app or per-route. It sets proper headers for client caching
  • Avoids the thundering heard by smartly refreshing the cache
  • Emits hit or miss events so you can track your hitrate
  • Simple invalidations
  • Overrides for custom cache keys and dev mode support
  • Obeys (some) client Cache-Control headers

What does it look like?

var Cacher = require("cacher")
// use the default in memory cache
var cacher = new Cacher()
// or pass in a different cache client (in this cached memcached) for different backend support
CacherMemcached = require('cacher-memcached')
var cacher = new Cacher(new CacherMemcached('host1:12345'))

// as a global middleware
app.use(cacher.cache('seconds', 30))
// or per route
app.get("/long-cache", cacher.cache('days'), ...)
app.get("/short-cache", cacher.cache('minute'), ...)
// will set no-cache headers for routes that we explicitly want to ignore caching on
app.get("/no-cache", cacher.cache(false), ...)

// Backwards compatible with old cache definitions
app.use(cacher.cacheHourly())
app.get("/long-cache", cacher.cacheDays(2), ...)

// invalidation support
cacher.invalidate('/home')

// listen for events to track cache rate and errors
cacher.on("hit", function(key) {
  console.log("woohoo!")
})
cacher.on("miss", function(key) {
  console.log("doh!")
})
cacher.on("error", function(err) {
  console.log(err)
})

// Dev mode, quickly turn off caching when it gets in the way
var env = process.env.NODE_ENV || 'development'
if (env === 'development') {
  cacher.noCaching = true
}

// override cache key generation for finer grain control
cacher.genCacheKey = function(req) {
  return req.path + req.header('user-agent')
}

// override cache TTL based on response
cacher.genCacheTtl = function(res, origTtl) {
  if (res.statusCode >= 400) {
    return 0
  }
  return origTtl
}

Backends

Currently, Cacher comes bundled with an in-memory cache

Backends are distributed as separate modules:

Backend Client Api

If you want to implement your own backend, the API is really simple:

// pass whatever options are needed for connection/options
// provide defaults so a client can be fully instantiated with no parameters
function MyBackend(...) {
}

// cb is required, cb(err, cacheObject)
MyBackend.prototype.get = function(key, cb) {}

MyBackend.prototype.set = function(key, cacheObject, ttlInSeconds, [cb]) {}

MyBackend.prototype.invalidate = function(key, [cb]) {}

Testing your backend

Run unit tests using your backend by doing the following:

cd Cacher
npm link ../myBackend
CACHER_CLIENT=myBackend npm test
Something went wrong with that request. Please try again.