npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@bbc/http-transport-cache

v4.4.0

Published

Caching middleware

Downloads

3,207

Readme

NPM downloads npm license github-issues stars forks

HTTP Transport Cache

A HTTP spec compliant caching layer for http-transport.

Installation

npm install --save http-transport-cache

Usage

Configure response caching based on max-age:

const cache = require('@bbc/http-transport-cache');
const Catbox = require('@hapi/catbox');
const HttpTransport = require('@bbc/http-transport');

const catbox = new Catbox.Client(new Memory());

const url = 'http://example.com/';

const client = HttpTransport.createBuilder()
      .use(cache.maxAge(catbox))
      .createClient();

      const body = await client.get(url)
        .asBody();

      console.log(body);

Configure stale-if-error:

const cache = require('@bbc/http-transport-cache');
const Catbox = require('catbox');
const HttpTransport = require('@bbc/http-transport');

const catbox = new Catbox.Client(new Memory());

const url = 'http://example.com/';

const client = HttpTransport.createClient()
      .use(cache.staleIfError(catbox))
      .createClient();

      const body = await client.get(url)
        .asBody();

      console.log(body);

Listening to Events:

const { events, maxAge } = require('@bbc/http-transport-cache');

const stats = require('@ibl/stats');
const Catbox = require('catbox');
const HttpTransport = require('@bbc/http-transport');

const catbox = new Catbox.Client(new Memory());

const url = 'http://example.com/';

const client = HttpTransport.createBuilder()
  .use(cache.maxAge(catbox, {
    name: `theservice`,
  }))
  .createClient();

events.on(`cache.theservice.read_time`, (ctx) => {
  stats.timing(`timingstat.read_time`, ctx.duration);
});

Features

|Feature|Description| |----|-----------| |Warnings|The cached response only contains the simplified http-transport request and response so as not to waste cache space.| |Max Age|Responses are stored for the duration of the max-age directive and are used before any requests are made.| |Stale If Error|In order to ensure a resilient service even during errors, http responses can include a cache-control directive called stale-if-error which means we can use a cached response for that period whilst the service is erroring. To do this a separate response blob is stored for the stale period and on error this response is used alongside the body which is stored for the higher of either max-age or stale-if-error.| |No Store|If no-store directive is present in the response, it will not be stored / cached anywhere.| |Private|If private directive is present in the response, it will not be stored by shared cache. The response will only be stored in a private cache intended for a single user.|

Events

  • hit
  • miss
  • error
  • timeout
  • stale
  • read_time
  • write_time
  • connection_error

Middleware Options

Both maxage and staleIfError accept an options object.

|Property|type|module|Description| |----|----|----|-----------| |ignoreCacheErrors|boolean|maxAge,staleIfError| cache.maxAge will return a cache miss when this property is true. Setting this property true for cache.staleIfError will rethrow the original error (not the cache lookup error). ignoreCacheErrors is false by default.| |timeout|integer|maxAge|Timeouts a cache lookup after a specified number of ms. By default, no timeout is specified.| |connectionTimeout|integer|maxAge,staleIfError|Timeouts the attempt to connect to a cache after a specified number of ms. By default, no timeout is specified.| |connectionCircuitBreakerOptions|object|maxAge,staleIfError| When present an instance of Levee will be created with these configuration options to use on connection to cache.| |includeCacheStatusInCtx|boolean|maxAge,staleIfError| When present, a cacheStatus array - recording all cache events, will be set in context for use by other plugins. includeCacheStatusInCtx is false by default.|

Cache version

The cache verison is stored in the config.json, this is distinct from the library version in the package.json. The cache version is used in the cache key and is intended to reduce cache fragmentation in a scenario where multiple different versions of this library might be in use across a single estate.

The cache version must be incremented if a change is made to the data stored in the cache that would be incompatible with the existing version. Otherwise it should not be changed.

Cache Key Structure

The cache uses catbox to provide a simple pluggable interface, this supports segmenting the cache as well as IDs, thus the following segments are used:

  • http-transport:{version}:response - Basic response from a call cached for the duration of the max-age value key on just the URL of the response.
  • http-transport:{version}:staleResponse - Stale response from a called cached for the stale-if-error value keyed on just the URL of the response.

Additionally, cache keys can be configured by passing a varyOn option. varyOn should contain an array of request header names which the cache should additionally vary on; for some use-cases, requests made to the same endpoint but with differing values for certain headers elicit different responses - and therefore cannot share the same cached response e.g.accept-language. By letting http-transport-cache know which headers to vary on, a unique cache key will be constructed which also contains said headers and their values.

Example:

We make a GET request to the following URL: www.example.com/some-cacheable-path.

We vary on accept-language and accept. These headers will exist in the request. We pass in varyOn (an array of request headers we vary on) together with other options to configure the plugin.

const opts = {
  timeout: 2000,
  varyOn: [
    'accept-language',
    'accept'
  ]
};

On the first request, the value of accept-language is en and accept is application/json. The resulting key will be:

  • GET:www.example.com/some-cacheable-path:accept-language=en,accept=application/json

On the second request, the value of accept-language is fr and accept is text/html. The resulting key will be:

  • GET:www.example.com/some-cacheable-path:accept-language=fr,accept=text/html

This way we avoid overwritting data in the store.

Test

npm test

To generate a test coverage report:

npm run coverage