Last active
September 16, 2020 22:21
-
-
Save nautilytics/1e362e7675e374b65e6584fcdf3e7311 to your computer and use it in GitHub Desktop.
Using Redis to cache API calls (Node.js)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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(); | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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