Shared Cache Between Laravel and node.js Using Redis
Cache Sharing Between Laravel and node.js Using Redis
Sometimes you have two applications which share their cache so you can reduce persistent storage transaction. Yeah, that’s pretty easy if both of them using same language or maybe same framework. But, let’s assume, how if one of them is using PHP (Laravel) and the other one is using node.js? This article will guide you to make your Laravel application can share it’s cache to node.js application, in another words, your node.js application may be able to read your Laravel cache.
Installation and Configuration
First, you have to configure your Laravel application to use Redis as it’s cache storage. In your config/cache.php
file, adjust your cache storage like this:
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Cache Store
|--------------------------------------------------------------------------
|
| This option controls the default cache connection that gets used while
| using this caching library. This connection is used when another is
| not explicitly specified when executing a given caching function.
|
| Supported: "apc", "array", "database", "file", "memcached", "redis"
|
*/
'default' => env('CACHE_DRIVER', 'redis'),
// [... OMITTED ...]
Or, change it from your .env
file:
CACHE_DRIVER=redis
Next, install predis/predis
package to use Redis with Laravel. This package is not included in default Laravel framework bundle.
composer require "predis/predis:~1.0"
Notes: You also have to install
redis
extension for PHP firstly. See more here.
Next, to make sure that you only get the exact cache data from Laravel application, you need to adjust your prefix cache key. To do so, change your config/cache.php
file into something like this:
<?php
return [
// [... OMMITED ...]
/*
|--------------------------------------------------------------------------
| Cache Key Prefix
|--------------------------------------------------------------------------
|
| When utilizing a RAM based store such as APC or Memcached, there might
| be other applications utilizing the same cache. So, we'll specify a
| value to get prefixed to all our keys so we can avoid collisions.
|
*/
'prefix' => 'fus_ro_dah',
];
Storing Cache
There’s no different between storing cache in Redis and storing cache in other supported Laravel cache provider (eg: memcached, file, etc). You know, kinda like this:
<?php
Cache::put('fus', 'ro_dah', 1); // Put cache with key 'fus' and value 'ro_dah' with ttl 1 minute
Notes: You can learn more about storing cache in laravel here.
If you check from Redis CLI, you can see fus
in there:
$ redis-cli
127.0.0.1:6379> KEYS fus_ro_dah:*
1) "fus_ro_dah:fus"
127.0.0.1:6379>
From that output, you may notice that your cache key is prefixed by fus_ro_dah:
string. This behavior is configurable via cache.cache_prefix
configuration.
Notes: You can learn more about Redis CLI here.
Getting Laravel Cache from node.js Application
After we store a cache, the next problem is getting the cache data from other application, such as from node.js application. Since we use Redis as our cache provider, we must require redis package to our node.js application.
npm install redis --save
To get Redis cache from Laravel application, tell node.js the Laravel’s cache_prefix
value, in this case it’s fus_ro_dah
. For example, I create an index.php
file like this:
var redisClient = require('redis').createClient();
redisClient.get('fus_ro_dah:fus', function (err, reply) {
console.log(reply); // Output s:6:"ro_dah";
});
You may notice that, the reply from Redis is an PHP encoded value:
$ node index.js
s:6:"ro_dah";
$
To make this reply is usable by node.js application, you may replace some string in it:
var redisClient = require('redis').createClient();
redisClient.get('fus_ro_dah:fus', function (err, reply) {
reply = (reply !== null)
? reply.replace(/^s:[0-9]*.:"/, '').replace(/";$/, '')
: reply;
console.log(reply); // Output "ro_dah"
});
Storing JSON file to Cache and Retrive It’s Value Using node.js
In some cases, we need to store our database result to database and we need it on our node.js application. If you uses the code above to strip PHP encoded string, then there’s no need for you to change your code:
<?php
Cache::put('fus', json_encode(['ro' => 'dah']), 1); // Example only
With this script:
var redisClient = require('redis').createClient();
redisClient.get('fus_ro_dah:fus', function (err, reply) {
reply = (reply !== null)
? reply.replace(/^s:[0-9]*.:"/, '').replace(/";$/, '')
: reply;
console.log(reply);
});
The output from code above is:
$ node index.js
{"ro":"dah"}
$
Or, if you want to get a JSON value, you can use JSON.parse
method:
var redisClient = require('redis').createClient();
redisClient.get('fus_ro_dah:fus', function (err, reply) {
reply = (reply !== null)
? JSON.parse(reply.replace(/^s:[0-9]*.:"/, '').replace(/";$/, ''))
: reply;
console.log(reply);
});
The output from code above is:
$ node index.js
{ ro: 'dah' }
$
Conclusion
If you build two applications that utilize same database, you can reduce database transaction by using cache. But sometimes, these two applications built with different language. In this case, you need a cache provider which can be used for many programming languages, Redis is one of them. Laravel and node.js is a good example to achieve this. After you read this article, you may implement this idea to your project, so you can reduce the database transaction, make your application faster, and of course without losing data consistency. If you have another idea or trouble in implementing this idea, let me know in comment below. Happy code!