npm i --save adonis-redis
You are viewing the legacy version of AdonisJS. Visit https://adonisjs.com for newer docs. This version will receive security patches until the end of 2021.
Support for multiple redis connections.
Connect to redis cluster.
Support for sentinel and transactions.
Extensive support for Pub/Sub.
ES2015 Generators friendly.
Redis provider is not shipped with the base installation of AdonisJs, which means you are required to install and set it up manually.
npm i --save adonis-redis
const providers = [
// ...
'adonis-redis/providers/RedisFactoryProvider',
'adonis-redis/providers/RedisProvider'
// ...
]
const aliases = {
// ...
Redis: 'Adonis/Addons/Redis'
// ...
}
Also, a configuration file needs to be saved as config/redis.js. You can download the sample configuration from github or run the below bash command to save the file automatically.
wget https://raw.githubusercontent.com/adonisjs/adonis-redis/develop/examples/redis.js -O config/redis.js
Once everything is configured, you are good to make use of Redis inside your AdonisJs applications. Let’s start with a basic example of caching users inside redis.
Below example may not be the best way to cache users but does give you some idea on how to use the redis provider. |
'use strict'
const Redis = use('Redis')
const User = use('App/Model/User')
class UsersController {
* index (request, response) {
const cachedUsers = yield Redis.get('users')
if (cachedUsers) {
response.json(JSON.parse(cachedUsers))
return
}
const users = yield User.all()
yield Redis.set('users', JSON.stringify(users))
response.json(users)
}
}
All redis commands are supported as javascript functions. For example:
'use strict'
const Redis = use('Redis')
const user = {
username: 'foo',
email: 'foo@bar.com'
}
yield Redis.hmset('users', user.username, JSON.stringify(user))
const user = yield Redis.hmget('users', user.username) // returns stringified JSON
Redis has built-in support for Pub/Sub to share messages on same or across multiple servers. AdonisJs offers a clean API to subscribe and publish messages without any extra efforts.
It is recommended to create a new file inside the bootstrap directory to register subscribers.
'use strict'
const Redis = use('Redis')
Redis.subscribe('music', function * (track) {
console.log('received track', track)
})
Next, you need to require this file inside bootstrap/http.js
file to make sure it is loaded when booting the HTTP server just after the require('./events')
statement.
require('./redis')
Now anywhere inside your application, you can publish to the music channel and the registered listener will be called.
'use strict'
const Route = use('Route')
const Redis = use('Redis')
Route.post('musics', function * (request, response) {
Redis.publish('music', request.all())
})
Below is the list of pub/sub methods exposed by the Redis Provider.
Redis.subscribe('music', function * (track, channel) {
console.log(track)
})
Also, the listener
can be a reference to a module inside app/Listeners
directory.
Redis.subscribe('music', 'Music.newTrack')
'use strict'
const Music = exports = module.exports = {}
Music.newTrack = function * (track, channel) {
console.log(track)
}
The psubscribe
method will subscribe to a pattern, and matching messages will be sent to the listener.
Redis.psubscribe('h?llo', function * (message, channel, pattern) {
})
Redis.publish('hello')
Redis.publish('hallo')
Publish message to a given channel.
Redis.publish('music', {id: 1, title: 'Love me like you do', artist: 'Ellie goulding'})
Transactions are helpful when you want to perform bulk operations at a given point of time. Let’s review an example of adding users to a list.
'use strict'
const User = use('App/Model/User')
const Redis = use('Redis')
class UsersController {
* index (request, response) {
const users = yield User.all()
// Creating a transaction
const multi = Redis.multi()
users.each((user) => {
multi.lpush('users-list', JSON.stringify(user))
})
yield multi.exec()
response.json(users)
}
}
Creates a new transaction to call multiple commands and execute them together.
const multi = Redis.multi()
multi
.set('foo', 'bar')
.set('bar', 'baz')
const response = yield multi.exec()
// [[null, 'OK'], [null, 'OK']]
Pipelines are quite similar to transactions, but they do not guarantee that all commands will be executed in a transaction. Pipelines are helpful in sending a batch of commands to save network round trips.
const pipeline = Redis.pipeline()
pipeline
.set('foo', 'bar')
.set('bar', 'baz')
const response = yield pipeline.exec()
// [[null, 'OK'], [null, 'OK']]
You can define the configuration for multiple connections inside the config/redis.js
file, and you can use those connections by calling the connection
method.
module.exports = {
connection: 'local',
local: {
...
},
secondary: {
host: 'myhost.com',
port: 6379
}
}
AdonisJs creates a connection pool to re-use the established connnection. Make use of the quit
method to close a single/all redis connections.
const response = yield Redis.quit('secondary')
// or
const response = yield Redis.quit() // close all connections
You can register a listener for lifecycle events in the same way you will do for Pub/Sub.
'use strict'
const Redis = use('Redis')
Redis.on('connect', function () {
// ...
})
Redis.on('error', function (error) {
// ...
})
Below is the list of events emitted by the Redis provider.
Event | Description |
---|---|
connect |
emits when a connection is established to the Redis server. |
ready |
emits when |
error |
emits when an error occurs while connecting with a property of |
close |
emits when an established Redis server connection has closed. |
reconnecting |
emits after |
end |
emits after |
+node |
emits when a new node is connected. |
-node |
emits when a node is disconnected. |
node error |
emits when an error occurs when connecting to a node |