diff --git a/README.md b/README.md
index df3ed92..06737ee 100644
--- a/README.md
+++ b/README.md
@@ -64,24 +64,20 @@ const onionoo = new Onionoo({
'clients',
'uptime'
],
- cache: {
- store: 'memory',
- ttl: 18000,
- max: 500
- }
+ cache: false
});
```
-## Cache Stores
+## Cache
-This module makes use of [`node-cache-manager`](https://github.com/BryanDonovan/node-cache-manager) to support multiple cache stores. By default cached responses are stored in memory. You can easily disable the cache or use a more scalable cache store such as Redis by using `node-cache-manager`'s [store engine](https://github.com/BryanDonovan/node-cache-manager#store-engines) modules.
+By default no cache is used. You can easily cache in memory or to a more scaleable store like Redis using [Keyv storage adapters](https://github.com/lukechilds/keyv#official-storage-adapters).
-Disable cache:
+Cache in memory:
```js
const Onionoo = require('onionoo');
const onionoo = new Onionoo({
- cache: false
+ cache: new Map()
});
```
@@ -89,11 +85,12 @@ Use persistent Redis cache:
```js
const Onionoo = require('onionoo');
-const redisStore = require('cache-manager-redis');
+const KeyvRedis = require('@keyv/redis');
+
+const redis = new KeyvRedis('redis://user:pass@localhost:6379');
+
const onionoo = new Onionoo({
- cache: {
- store: redisStore
- }
+ cache: redis
});
```
@@ -123,10 +120,10 @@ Array of endpoints to be returned as methods on the `Onionoo` instance.
##### options.cache
-Type: `object`, `boolean`
-Default: `{ store: 'memory', ttl: 18000, max: 500 }`
+Type: `object`
+Default: `false`
-Options object to be merged with default options and passed to [`node-cache-manager`](https://github.com/BryanDonovan/node-cache-manager). Alternatively, if set to false, caching will be disabled.
+[Keyv](https://github.com/lukechilds/keyv) storage adapter instance for storing cached data.
### onionoo.endpoint([query])
diff --git a/package.json b/package.json
index 8ef9bc6..b591ff5 100644
--- a/package.json
+++ b/package.json
@@ -26,16 +26,11 @@
},
"homepage": "https://github.com/lukechilds/onionoo-node-client",
"dependencies": {
- "cache-manager": "2.5.0",
- "deep-assign": "2.0.0",
- "expired": "1.3.12",
"got": "8.0.0"
},
"devDependencies": {
"ava": "^0.24.0",
"coveralls": "^3.0.0",
- "date-fns": "^1.21.1",
- "delay": "^2.0.0",
"nock": "^9.0.2",
"nyc": "^11.0.0",
"xo": "^0.19.0"
diff --git a/src/index.js b/src/index.js
index d35720a..5867c64 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,8 +1,5 @@
const querystring = require('querystring');
const got = require('got');
-const cacheManager = require('cache-manager');
-const expired = require('expired');
-const deepAssign = require('deep-assign');
const pkg = require('../package.json');
class Onionoo {
@@ -21,13 +18,6 @@ class Onionoo {
'uptime'
]
}, options);
- if (options.cache !== false) {
- this.options.cache = cacheManager.caching(Object.assign({
- store: 'memory',
- ttl: 18000, // 5 hours
- max: 500
- }, options.cache));
- }
// Return object containing endpoint methods
return this.options.endpoints.reduce((onionoo, endpoint) => {
@@ -46,75 +36,14 @@ class Onionoo {
let url = `${this.options.baseUrl}/${endpoint}`;
url += qs ? `?${qs}` : '';
- // If caching is disabled, just make the request
- if (!this.options.cache) {
- return this.makeRequest(url);
- }
-
- // If caching is enabled, check for url in cache
- return this.options.cache.get(url)
- .then(cachedResult => {
- const options = {};
-
- // If we have it cached
- if (cachedResult) {
- // Return the cached entry if it's still valid
- if (!expired(cachedResult.headers)) {
- return cachedResult;
-
- // If it's stale, add last-modified date to headers
- } else if (cachedResult.headers['last-modified']) {
- options.headers = {
- 'if-modified-since': cachedResult.headers['last-modified']
- };
- }
- }
-
- // Make a request
- return this.makeRequest(url, options)
- .then(response => {
- // If we get a 304, fill in the body
- if (response.statusCode === 304) {
- response.body = cachedResult.body;
- }
-
- // If we get a 200 or 304, cache it
- if ([200, 304].includes(response.statusCode)) {
- this.options.cache.set(url, response);
- }
-
- return response;
- });
- });
- }
-
- // Returns a promise for a request
- makeRequest(url, options = {}) {
- options = deepAssign({
+ // Make request
+ return got(url, {
headers: {
'user-agent': `onionoo-node-client v${pkg.version} (${pkg.homepage})`
- }
- }, options);
-
- return got(url, options)
- .catch(err => {
- // Don't throw 304 responses
- if (err.statusCode === 304) {
- return err.response;
- }
- throw err;
- })
- .then(response => {
- // Format response
- response = {
- statusCode: response.statusCode,
- statusMessage: response.statusMessage,
- headers: response.headers,
- body: response.body && JSON.parse(response.body)
- };
-
- return response;
- });
+ },
+ json: true,
+ cache: this.options.cache
+ });
}
}
diff --git a/test/cache.js b/test/cache.js
index 6d252da..baf33d5 100644
--- a/test/cache.js
+++ b/test/cache.js
@@ -1,12 +1,10 @@
import test from 'ava';
import nock from 'nock';
-import subSeconds from 'date-fns/sub_seconds';
-import delay from 'delay';
import Onionoo from '../';
import data from './fixtures/data';
-test('Cache can be disabled', async t => {
- const onionoo = new Onionoo({cache: false});
+test('Cache is disabled by default', async t => {
+ const onionoo = new Onionoo();
const defaultEndpoint = data.defaultEndpoints[0];
const responseHeaders = {
@@ -21,7 +19,7 @@ test('Cache can be disabled', async t => {
const response = await onionoo[defaultEndpoint]();
- t.deepEqual(response.body, data.dummyResponse);
+ t.false(response.fromCache);
t.truthy(scope.isDone());
const scope2 = nock(data.defaultBaseUrl)
@@ -30,12 +28,12 @@ test('Cache can be disabled', async t => {
const response2 = await onionoo[defaultEndpoint]();
- t.deepEqual(response2.body, data.dummyResponse);
+ t.false(response2.fromCache);
t.truthy(scope2.isDone());
});
-test('Responses with future max-age are cached', async t => {
- const onionoo = new Onionoo();
+test('Cache options is passed through to Got', async t => {
+ const onionoo = new Onionoo({cache: new Map()});
const defaultEndpoint = data.defaultEndpoints[0];
const responseHeaders = {
@@ -50,84 +48,10 @@ test('Responses with future max-age are cached', async t => {
const response = await onionoo[defaultEndpoint]();
- t.deepEqual(response.body, data.dummyResponse);
+ t.false(response.fromCache);
t.truthy(scope.isDone());
- const cachedResponse = await onionoo[defaultEndpoint]();
-
- t.deepEqual(cachedResponse.body, data.dummyResponse);
-});
-
-test('Responses older than max-age are not cached', async t => {
- const onionoo = new Onionoo();
-
- const defaultEndpoint = data.defaultEndpoints[0];
- const responseHeaders = {
- date: subSeconds(new Date(), 15).toUTCString(),
- age: 0,
- 'cache-control': 'public, max-age=10'
- };
-
- const scope = nock(data.defaultBaseUrl)
- .get(`/${defaultEndpoint}`)
- .reply(200, data.dummyResponse, responseHeaders);
-
- const response = await onionoo[defaultEndpoint]();
-
- t.deepEqual(response.body, data.dummyResponse);
- t.truthy(scope.isDone());
-
- const scope2 = nock(data.defaultBaseUrl)
- .get(`/${defaultEndpoint}`)
- .reply(200, data.dummyResponse, responseHeaders);
-
const response2 = await onionoo[defaultEndpoint]();
- t.deepEqual(response2.body, data.dummyResponse);
- t.truthy(scope2.isDone());
-});
-
-test('When expired, add last-modified date to headers and handle 304', async t => {
- const onionoo = new Onionoo();
-
- const defaultEndpoint = data.defaultEndpoints[0];
- const initialDate = new Date().toUTCString();
- const responseHeaders = {
- date: initialDate,
- age: 0,
- 'cache-control': 'public, max-age=1',
- 'last-modified': initialDate
- };
-
- const scope = nock(data.defaultBaseUrl)
- .get(`/${defaultEndpoint}`)
- .reply(200, data.dummyResponse, responseHeaders);
-
- const response = await onionoo[defaultEndpoint]();
-
- t.deepEqual(response.body, data.dummyResponse);
- t.truthy(scope.isDone());
-
- const requestHeaders = {
- 'if-modified-since': initialDate
- };
- const responseHeaders304 = {
- date: new Date().toUTCString(),
- age: 0,
- 'cache-control': 'public, max-age=10',
- 'last-modified': initialDate
- };
-
- const scope2 = nock(data.defaultBaseUrl, {requestHeaders})
- .get(`/${defaultEndpoint}`)
- .reply(304, null, responseHeaders304);
-
- const response2 = await delay(2000).then(onionoo[defaultEndpoint]);
-
- t.deepEqual(response2.body, data.dummyResponse);
- t.truthy(scope2.isDone());
-
- const cachedResponse = await onionoo[defaultEndpoint]();
-
- t.deepEqual(cachedResponse.body, data.dummyResponse);
+ t.true(response2.fromCache);
});