├── .eslintrc ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── index.js ├── package.json └── test └── connection.js /.eslintrc: -------------------------------------------------------------------------------- 1 | env: 2 | node: true 3 | 4 | rules: 5 | no-underscore-dangle: 0 6 | no-use-before-define: 0 7 | quotes: [0, single] 8 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | 10 | pids 11 | logs 12 | results 13 | 14 | npm-debug.log 15 | node_modules 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "0.10" 5 | - "0.12" 6 | - "iojs" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 James Butler 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://secure.travis-ci.org/sandfox/node-hapi-redis.png)](http://travis-ci.org/sandfox/node-hapi-redis) 2 | [![Dependencies Status](https://david-dm.org/sandfox/node-hapi-redis.png)](https://david-dm.org/sandfox/node-hapi-redis) 3 | [![DevDependencies Status](https://david-dm.org/sandfox/node-hapi-redis/dev-status.png)](https://david-dm.org/sandfox/node-hapi-redis#info=devDependencies) 4 | 5 | # Hapi-Redis 6 | 7 | This is a plugin to share a common redis connection across the whole Hapi server. 8 | 9 | __This version is intended for use with hapi v8.x.x__ 10 | 11 | __If you are looking for a version that works with hapi v7.x.x then please use version 1.x.x__ 12 | 13 | __As of 3.x.x it is now possible to register this plugin multiple times__ 14 | 15 | __As of 4.x.x it is now possible to supply a connection string as the `option`__ 16 | 17 | ~~__As of 4.x.x `redis` is now a peer dependency (0.12.x) to allow users more freedom with redis versions__~~ 18 | 19 | __As of 5.x.x we've scrapped redis as a peer deps__ 20 | 21 | __With 6.x.x the `options` object has changed it's signature__ 22 | 23 | ## Registering the plugin 24 | 25 | Options: 26 | - `redisLibrary`: passing in a `redis` module to override the one bundled with this module. optional. 27 | - `connection`: an object or string that is passed through to [basic-redis-factory](https://github.com/sandfox/node-basic-redis-factory/tree/v0.0.3#api) as the 2nd argument. The relevant part of the docs are reproduced here for ease of reference: 28 | 29 | `connection` can either be a url connection string (i.e `redis://user:password@127.0.0.1:6379`) or an object. 30 | 31 | if `connection` is an object then the factory will look for the following keys on the object 32 | and fallback to defaults for any missing values (host: `127.0.01`, port: `6379`, no authentication). 33 | 34 | - `url` : a url connection string. 35 | - `host`: the host to connect to. 36 | - `port`: the port to connect to. 37 | - `password`: the password to authenticate with, if not supplied then no auth will applied. 38 | - `opts`: an options object as expected by [`redis.createClient`](https://github.com/mranney/node_redis#rediscreateclient). 39 | 40 | If `opts.url` is supplied then `opts.host`, `opts.port`, and `opts.password` keys will be ignored. 41 | 42 | If you wish to use the `hiredis` parser then just: 43 | ``` 44 | npm install -save hiredis 45 | ``` 46 | and this module will automatically use it (unless you override that with the `parser` option). 47 | 48 | The registration of this plugin will only complete on either succesful connection to the redis instance or an error. 49 | 50 | ## Using the plugin 51 | 52 | Two objects are exposed by this plugin : 53 | 54 | - `client` : a redis client connection object that is connected to the redis instance 55 | - `library`: the redis module used by this module 56 | 57 | ## Example 58 | 59 | ```js 60 | var Hapi = require("hapi"); 61 | 62 | var myPluginOpts = { 63 | connection: { 64 | "host": "localhost" 65 | "opts": { 66 | "parser": "javascript" 67 | } 68 | } 69 | }; 70 | 71 | var server = new Hapi.Server(8080); 72 | 73 | server.pack.register({ 74 | register: require('hapi-redis'), 75 | options: myPluginOpts 76 | }, function () { 77 | 78 | }); 79 | 80 | server.route( { 81 | "method" : "GET", 82 | "path" : "/stats", 83 | "handler" : usersHandler 84 | }); 85 | 86 | function usersHandler(request, reply) { 87 | var redisClient = request.server.plugins['hapi-redis'].client; 88 | 89 | // Do something with the redis client 90 | // reply(result); 91 | }; 92 | 93 | server.start(function() { 94 | console.log("Server started at " + server.info.uri); 95 | }); 96 | ``` 97 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var redis = require('redis'); 4 | var redisClientFactory = require('basic-redis-factory'); 5 | 6 | exports.register = function (server, options, next) { 7 | 8 | options = options || {}; 9 | 10 | var redisOpts = options.connection; 11 | 12 | var redisLibrary = options.redisLibrary || redis; 13 | 14 | var redisClient = redisClientFactory(redisLibrary, redisOpts); 15 | 16 | /** 17 | * error handler for errors after initial connection has been established 18 | * @param {Error} err is the error thrown 19 | * @return {null} 20 | */ 21 | var defaultErrorHandler = function(err) { 22 | server.log([ 'hapi-redis', 'error' ], err.message); 23 | }; 24 | 25 | var initialErrorHandler = function(err) { 26 | server.log([ 'hapi-redis', 'error' ], err.message); 27 | next(err); 28 | redisClient.end(); 29 | }; 30 | 31 | redisClient.on('error', initialErrorHandler); 32 | 33 | redisClient.on("ready", function(){ 34 | server.log([ 'hapi-redis', 'info' ], 'redisClient connection created'); 35 | 36 | // change the error handler to simply log errors 37 | redisClient.removeListener('error', initialErrorHandler); 38 | redisClient.on('error', defaultErrorHandler); 39 | next(); 40 | }); 41 | 42 | server.expose('client', redisClient); 43 | server.expose('library', redisLibrary); 44 | 45 | }; 46 | 47 | exports.register.attributes = { 48 | pkg: require('./package.json'), 49 | multiple: true 50 | }; 51 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hapi-redis", 3 | "version": "7.0.0-beta1", 4 | "description": "redis client plugin for hapi", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "NODE_ENV=test mocha", 8 | "testwatch": "NODE_ENV=test mocha -w", 9 | "lint": "eslint index.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git://github.com/sandfox/node-hapi-redis.git" 14 | }, 15 | "keywords": [ 16 | "hapi", 17 | "redis", 18 | "plugin" 19 | ], 20 | "author": "sandfox", 21 | "license": "MIT", 22 | "devDependencies": { 23 | "eslint": "^0.24.0", 24 | "fakeredis": "^0.3.2", 25 | "hapi": "^8.2.0", 26 | "mocha": "^2.0.1" 27 | }, 28 | "dependencies": { 29 | "redis": "^2.3.0", 30 | "basic-redis-factory": "0.0.3" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/connection.js: -------------------------------------------------------------------------------- 1 | var Hapi = require('hapi'); 2 | var assert = require('assert'); 3 | 4 | var fakeClient = require('fakeredis'); 5 | 6 | var redisPlugin = require('../'); 7 | 8 | describe('Redis client plugin', function() { 9 | 10 | it('should be able to register the plugin with default options', function(done) { 11 | var server = new Hapi.Server(); 12 | server.register({ 13 | register: redisPlugin, 14 | options: {redisLibrary: fakeClient} 15 | }, function () { 16 | assert(server.plugins['hapi-redis'].client,'no redis client was returned'); 17 | server.plugins['hapi-redis'].client.ping(function(err, res){ 18 | assert.equal(res, 'PONG', "didn't get a pong for our ping") 19 | done() 20 | }) 21 | }); 22 | }); 23 | 24 | it('should throw error if redis connection fails', function(done) { 25 | var server = new Hapi.Server(); 26 | server.register({ 27 | register: redisPlugin, 28 | options: { 29 | host: 'invalid' 30 | } 31 | }, function (err) { 32 | assert(err instanceof Error, 'No error thrown for failed connection') 33 | done() 34 | }); 35 | }); 36 | }); 37 | --------------------------------------------------------------------------------