6 minutes

Shared Cache Between Laravel and node.js Using Redis

Cache Sharing Between Laravel and node.js Using Redis

Published Aug 22, 2016
Scroll

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!

7 minutes

Debugging Happily in Yii2

Variable Dumping in Yii2 has never been so easy until you read this

Published Aug 11, 2016 in