Skip to content

Instantly share code, notes, and snippets.

@nautilytics
Last active September 16, 2020 22:21
Show Gist options
  • Save nautilytics/1e362e7675e374b65e6584fcdf3e7311 to your computer and use it in GitHub Desktop.
Save nautilytics/1e362e7675e374b65e6584fcdf3e7311 to your computer and use it in GitHub Desktop.
Using Redis to cache API calls (Node.js)
const rp = require('request-promise');
const { to } = require('await-to-js');
const crypto = require('crypto');
const redisClient = require('./redis-client');
/**
* Execute an API call
* @param {String} uri API URI
* @param {Number} ttl Expiration of cache in seconds
*/
const cachingQuery = (module.exports = (uri, ttl = 0) => {
return new Promise(async (resolve, reject) => {
let err, results;
const hash = crypto
.createHash('sha1')
.update(uri)
.digest('hex');
redisClient.getCache(hash, async (err, data) => {
if (err || !data) {
[err, results] = await to(_execute(uri, ttl));
if (err) return reject(err);
return resolve(results);
} else {
return resolve(data);
}
});
});
});
function _execute(uri, ttl) {
return new Promise((resolve, reject) => {
const hash = crypto
.createHash('sha1')
.update(uri)
.digest('hex');
const options = {
uri,
headers: {},
json: true,
};
rp(options)
.then(result => {
redisClient.setCache(hash, ttl, result, (err, data) => {
if (err || !data) return reject('Error getting redis cache');
return resolve(result);
});
})
.catch(error => reject(error));
});
}
#!/usr/bin/env node
'use strict';
require('dotenv').config();
const rp = require('request-promise');
const query = require('./api-query');
const retrieveData = async () => {
let projects = await query('https://api.example.com/v1/projects', 3600); // ttl in seconds
return console.log(projects);
};
(async function() {
await retrieveData();
})();
const redis = require('redis');
const multicb = require('multicb');
const redisClient = (module.exports = redis.createClient(process.env.REDIS_PORT, process.env.REDIS_HOST, { no_ready_check: true }));
if (process.env.REDIS_PASSWORD) {
redisClient.auth(process.env.REDIS_PASSWORD);
}
redisClient.on('error', err => console.log('Redis ' + err));
setInterval(function() {
redisClient.ping();
}, 1000 * 30);
// =====================
// API caching functions
// =====================
redisClient.getCache = (key, next) => {
redisClient.get(`api:${key}`, (err, result) => {
if (err || !result) return next(err);
return next(null, JSON.parse(result));
});
};
redisClient.setCache = (key, ttl, data, next) => {
redisClient.setex(`api:${key}`, ttl, JSON.stringify(data), (err, result) => {
if (err || !result) return next(err);
return next(null, result);
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment