Introduction

Several of your application's data retrieval and processing activities may be CPU demanding and take several seconds to complete. When this happens, it's customary to save the obtained data in a cache so that it may be accessed fast on subsequent requests for the same information. Cache data is often saved in a fast data store like Memcached or Redis.

Fortunately, Ostro provides an expressive, consistent API for different cache backends, allowing you to benefit from their lightning-fast data retrieval and speed up your web application. 

Configuration

The cache configuration file for your application is config/cache.js. You can define which cache driver should be used by default across your programme in this file. Ostro comes with built-in support for common caching backends including Memcached, Redis, DynamoDB, and relational databases. A file-based cache driver is also available, as well as array and "null" cache drivers, which provide handy cache backends for your automated tests.

The cache configuration file also has a number of additional options, all of which are explained in the file, so make sure you go through them. Ostro is set up to utilise the file cache driver by default, which saves serialised, cached objects to the server's filesystem. It is suggested that you use a more robust driver, such as Memcached or Redis, for bigger applications. For the same driver, you may even set up different cache settings.

Driver Prerequisites

Database

You'll need to create a table to hold the cache entries if you're using the database cache driver. Below is an example of a Schema declaration for the table:

Schema.create('cache', function (table) {
    table.string('key').unique();
    table.text('value');
    table.integer('expiration');
});

Memcached

The Memcached driver requires the Memcached package to be installed before it can be used. In the config/cache.js configuration file, you may list all of your Memcached servers. To get you started, this file already has a memcached.servers entry:

'memcached' : {
    'servers' : {
        
            'host' : env('MEMCACHED_HOST', '127.0.0.1'),
            'port' : env('MEMCACHED_PORT', 11211),
            'weight' : 100,
        
    },
}

You can specify the host parameter to a UNIX socket path if necessary. If you do this, make sure the port option is set to 0:

'memcached' : {
    
        'host' : '/var/run/memcached/memcached.sock',
        'port' : 0,
        'weight' : 100
    
},

Redis

You must either install the Redis client through NPM before utilising a Redis cache with OstroJS. Consult the OstroJS manual page for additional information on configuring Redis.

DynamoDB

You must first build a DynamoDB table to contain all of the cached data before utilising the DynamoDB cache driver. Cache is a common name for this table. However, the table should be named after the value of the stores. dynamodb.table configuration value in the cache configuration file of your application

A string partition key with a name that matches to the value of the stores. dynamodb.attributes.key configuration item in your application's cache configuration file should also be included in this table. The partition key should be called key by default.

Cache Usage

Obtaining A Cache Instance

You may utilise the Cache façade to get a cache store instance, which is what we'll be using throughout this tutorial. The Cache façade offers quick and easy access to the OstroJS cache contracts' underlying implementations:

Accessing Multiple Cache Stores

The store method of the Cache facade may be used to access multiple cache stores. The key provided to the store function should match one of the stores in your cache configuration file's stores configuration object:

let $value = await Cache.store('file').get('foo');

await Cache.store('redis').put('bar', 'baz', 600); // 10 Minutes

Getting Items Out Of The Cache

The Cache facade's get method is used to retrieve items from the cache. If the item does not exist in the cache, null will be returned. If you want to define a default value to be returned if the item doesn't exist, you may send a second parameter to the get method:

let $value = await Cache.get('key');

let $value = await Cache.get('key', 'default');

You may even set the default value to a closure. If the requested item does not exist in the cache, the closure result will be returned. You can delay the retrieval of default values from a database or other external service by passing a closure:

let $value = await Cache.get('key', async function () {
    return await DB.table(...).get();
});

 

Incrementing / Decrementing Values

To change the value of integer items in the cache, utilise the increment and decrement methods. Both of these procedures take an optional second parameter specifying the amount by which the item's value should be increased or decreased:

await Cache.increment('key');
await Cache.increment('key', $amount);
await Cache.decrement('key');
await Cache.decrement('key', $amount);

Checking For Item Existence

To discover if an item exists in the cache, use the has method. If the item exists but the value is null, this function will return false:

if (await Cache.has('key')) {
    //
}

Retrieve & Store

If the requested item does not exist, you may want to retrieve it from the cache while simultaneously saving a default value. You could want to get all users from the cache or, if they don't exist, get them from the database and add them to the cache. You may accomplish this by using the Cache::remember technique :

let $value = await Cache.remember('users', $seconds, async function () {
    return await DB.table('users').get();
});

If the item isn't in the cache, the remember method's closure will be called, and the result will be stored in the cache.

The rememberForever method may be used to retrieve an item from the cache or to store it indefinitely if it does not exist:

let $value = Cache.rememberForever('users', async function () {
    return await DB.table('users').get();
});

 

Retrieve & Delete

The pull method may be used to obtain an item from the cache and subsequently remove the item. If the item does not exist in the cache, null will be returned, same as the get method:


let $value = await Cache.pull('key');

Storing Items In The Cache

To store things in the cache, use the put method on the Cache facade:

Cache.put('key', 'value', 10).then(status=>{

});

 // or 
await Cache.put('key', 'value', 10)

The object will be kept indefinitely if the storage time is not supplied to the put method:

await Cache.put('key', 'value');

 

Store If Not Present

If the item does not already exist in the cache storage, the add method will just add it to the cache. If the item is added to the cache, the method will return true. The method will return false if this is not the case. The add method is a one-of-a-kind action:

await Cache.add('key', 'value', $seconds);

Storing Items Forever

To keep an item in the cache indefinitely, use the forever technique. These items must be manually deleted from the cache using the forget technique since they will not expire.

await Cache.forever('key', 'value');

Removing Items From The Cache

The forget method may be used to delete things from the cache:


await Cache.forget('key');

You may also delete things by setting the expiration seconds to zero or negative:

await Cache.put('key', 'value', 0);

await Cache.put('key', 'value', -5);

The flush technique may be used to clear the whole cache:

await Cache.flush();

The Cache Helper

You may use the global cache function in addition to the Cache façade to get and put data in the cache. The value of the provided key is returned when the cache function is invoked with a single, string argument:

let $value = await cache('key');

The function will store values in the cache for the specified duration if you pass it an array of key/value pairs and an expiration time:

await cache({'key': 'value'}, $seconds);

await cache({'key':'value'}, now().addMinutes(10));