- Redis
- Cache concepts
- Activities
Redis is an open source, BSD licensed, advanced key-value cache and store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets, sorted sets, bitmaps and hyperloglogs.
- Cache everything.
- Have a standardized method for creating keys.
- Figure out early on if you want to cache an item.
- Redis gives you a few ways to make this happen.
- Hashes
- Known data structure
- Only
get
/set
what you need (this is something you have to figure out) - Slow
- Strings
- Serialize & De-serialize on each request.
- Hashes
Always check your cache. Drupal is slow, and you'll want to avoid making a network round-trip if you can.
Take advantage of multi-get. This prevents us from making multiple round-trips to Redis. This is especially important if Redis is not physically located near your front-end.
client.mget(['my-key', 'my-second-key'], function (err, data) {
console.log(err, data);
})
Require some new libraries we'll need for these activities.
- Copy
app.default.js
toapp.js
- Require
redis
,request
, andcrypto
. - Create a
redis
client,client = redis.createClient();
Install necessary modules
npm --save adaro express redis crypto request
var express = require('express'),
path = require('path'),
adaro = require('adaro'),
redis = require('redis'),
request = require('request'),
crypto = require('crypto'),
client = redis.createClient(),
app = express();
- Create a route that listens on
/posts
route. - Request data from Drupal
app.get('/posts', function (req, res) {
request({
url: 'http://USERNAME.drupal.train-headless.4kclass.com:8080/api/v1.2/articles',
json: true
}, function (error, response, body) {
return res.send(body);
});
});
Visit http://USERNAME.drupal.headless.train-headless.4kclass.com:PORT/posts
Every time someone makes a request for the /posts
route, an external data source will be fetched. The request()
function takes two parameters, an object with some options, and a callback; in the call back is where you can return the data.
url
is our remote environmentjson
lets request know that our response is JSON and it should automatically parse the response.
For the callback function you get three variables, error
, response
, body
.
Store the remote url and our cacheKey
as variables so they can be reused. Make sure these variables are declared within the app.get()
callback.
var remote = 'http://USERNAME.drupal.train-headless.4kclass.com:8080/api/v1.2/articles',
cacheKey = crypto.createHash('sha1').update(req.url + process.env.PORT).digest('hex');
- Change the
url
option of request to be theremote
variable.
Your cacheKey
is a sha1
hash of the request URL and the port (combined). This is something that should be unique to each request, otherwise you might accidentally return incorrect data.
Now, request the data at the specific key we just created. This should be included within the app.get()
callback. With just this you'll only see null, null
in the console; we haven't yet set the cache key.
client.get(cacheKey, function (err, reply) {
console.log(err, reply)
});
We only want to make requests to Drupal if there is nothing in our cache.
Every HTTP request you have to make will slow down your application. Speed matters. Cache everything!
client.get(cacheKey, function (err, reply) {
if (reply !== null) {
return res.send(reply);
}
else {
request({
url: remote,
json: true
}, function (error, response, body) {
return res.send(body);
});
}
});
In this instance we're only making a request to Drupal if the reply
from Redis was null
.
We can use the .set()
method from the node-redis library to save the response from Drupal in Redis.
client.set(key, value, function (err, reply) {
// DO STUFF
});
- Use
client.set()
to store the response from Drupal in Redis. - Ensure the JSON is stored as a string in Redis, and parsed when returned.
client.get(cacheKey, function (err, reply) {
if (reply !== null) {
return res.send(JSON.parse(reply));
}
else {
request({
url: remote,
json: true
}, function (error, response, body) {
client.set(cacheKey, JSON.stringify(body), function (err, reply) {
return res.send(body);
});
});
}
});
- Use a
multi object
to set cached data at it'sttl
. - Create a dust template to render this data.
- Create an optional route parameter to filter all posts by their id
- Change the template for this single post.