Set up cache with Redis in Node.js
It's 2020 and having a cache it's today a required part of your stack. For example, you could cache your database response for X time (or until a new entry comes in) to stop doing a query (or more!) for every request.
Recently I had to implement it in Node.js and I've chosen to go with Redis. I was looking for a decent but simple-to-use library and I didn't find so much, so I decided to write my own: Redache.
Let's see how to implement it!
Installation
To install the library, just run from your terminal yarn add redache
or, if you use npm: npm i redache --save
.
Then, of course, you have to include it in your project. If you use ES6 features, you can use import
:
import Redache from 'redache';
// ...
Otherwise, you can go with the CommonJS way:
const Redache = require('redache');
// ...
The last but not least step is to initialize it. This is a minimal configuration, but you can check out all the available parameters in the Redis official package: github.com/NodeRedis/node_redis#options-obj..
const cache = new Redache({
host: '127.0.0.1',
port: 6379,
password: 'foobar',
});
Save values
I wanted to keep the library as easy as possible. To store a value, you just have to call the .set()
method providing a key, a value and a TTL (expiration time).
Usually with these libraries, you have to specify the TTL as a number representing the seconds, but guess what? I didn't want to make your life harder, but easier, so... You can choose between four methods to specify your expiration and the first one si my favorite.
1. Human readable TTL Just pass a format like number TIME_UNIT
to set the expiration. It uses moment
behind the scenes to "decode" it, so TIME_UNIT
can be something like days
, day
, d
, month
and so on.
// It expires in 5 hours
await cache.set('key', 'value', '5 hours');
2. Date
instance If you're more "old school" and you have a Date
instance, don't worry, we accept it as well.
// It expires the 1st Jan 2050
await cache.set('key', 'value', new Date(2050, 1, 1));
3. moment
instance We said it uses moment
under the hood, so of course you can provide a moment
object.
// It expires in 1 month
await cache.set('key', 'value', moment().add(1, 'month'));
4. Seconds And finally, if you're a real boss, you can pass a number representing the seconds. I don't know why you should, but ehy, up to you!
// It expires in 3600 seconds -> 1 hour
await cache.set('key', 'value', 3600);
Object(s) and Array(s)
Most of the time you want to save a whole object or array, but the native Redis functions won't let you do that. But we do. Just pass your desired variable and the library will take care of JSON serializing and deserializing it.
Retrieve values
After you saved your value you may desire (or may not?) to retrieve it.
const value = await cache.get('key');
As we said, Redache accepts objects and arrays too, let's see how:
await cache.set('key', { foo: 'bar' }, '1 hour');
// Retrieve it
// It will be: { foo: 'bar' } but stored as '{"foo":"bar"}'
const value = await cache.get('key');
Easy, right? Now let's say that you want to store a value if a key is not found (or expired) on Redis, you would write something like:
let value = await cache.get('key');
if (value === null) {
value = 'my fallback';
await cache.set('key', 'my fallback', '1 day');
}
NOOOOOOO!! The library can manage this for you, in just one line! In fact, the 2nd and 3rd arguments of .get()
are, respectively, the fallback value and the fallback TTL.
const value = await cache.get('key', 'my fallback', '1 day');
Isn't it more simple? The fallback value accepts as well a function (async too):
const value = await cache.get('key', () => 'my fallback', '1 day');
// Async example
const value = await cache.get('key', () => Promise.resolve('my fallback'), '1day ');
Delete a key
Like alchemy, you can create and destroy (yes, I recently saw Fullmetal Alchemist). Just invoke .forget()
method specifying your key.
// Save a record
await cache.set('key', 'value', '1 day');
// It returns `value`
const value = await cache.get('key');
// Now let's remove it
await cache.forget('key');
// It will return null now, because we removed it
const valueAgain = cache.get('key');
Conclusion
That's it! I hope this library can help you as much as it helped me and don't forget to leave a star!