├── .gitignore ├── .travis.yml ├── README.md ├── index.js ├── package.json └── test ├── index.test.js └── server-example.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | .DS_Store 4 | coverage/ 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 4 4 | services: 5 | - redis-server 6 | before_install: 7 | - pip install --user codecov 8 | after_success: 9 | - codecov 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hapi-redis-connection 2 | 3 | [![Build Status](https://travis-ci.org/dwyl/hapi-redis-connection.svg?branch=master)](https://travis-ci.org/dwyl/hapi-redis-connection) 4 | [![codecov](https://codecov.io/gh/dwyl/hapi-redis-connection/branch/master/graph/badge.svg)](https://codecov.io/gh/dwyl/hapi-redis-connection) 5 | [![Code Climate](https://codeclimate.com/github/dwyl/hapi-redis-connection/badges/gpa.svg)](https://codeclimate.com/github/dwyl/hapi-redis-connection) 6 | [![dependencies Status](https://david-dm.org/dwyl/hapi-redis-connection/status.svg)](https://david-dm.org/dwyl/hapi-redis-connection) 7 | [![devDependencies Status](https://david-dm.org/dwyl/hapi-redis-connection/dev-status.svg)](https://david-dm.org/dwyl/hapi-redis-connection?type=dev) 8 | 9 | ![dilbert_in-memory](https://cloud.githubusercontent.com/assets/194400/17288192/05bed3d6-57d4-11e6-8870-19548218ca9e.jpg) 10 | 11 | ## *Why*? 12 | 13 | Redis is a *great* place to store data you need *fast* access to in your Hapi app. If you have many route handlers in separate files it can be *tedious* to `require()` (*or `import` if you prefer*) the `redis` module 14 | and establish a connection in each one ... so we created a tiny Plugin 15 | that gives you access to Redis in all your routes. 16 | 17 | 18 | ## *What*? 19 | 20 | A simple hapi module which makes a connection to your Redis store available 21 | anywhere in your Hapi server. 22 | 23 | ## *How*? 24 | 25 | ### 1. Download/Install 26 | 27 | Install the plugin/package from NPM: 28 | 29 | ```sh 30 | npm install hapi-redis-connection --save 31 | ``` 32 | 33 | ### 2. *Intialise* the plugin in your Hapi Server 34 | 35 | ```js 36 | server.register({ // register all your plugins 37 | register: require('hapi-redis-connection') // no options required 38 | }, function (err) { 39 | if (err) { 40 | // handle plugin startup error 41 | } 42 | }); 43 | ``` 44 | 45 | 46 | ### 3. *Use* `hapi-redis-connection` in your Route Handler 47 | 48 | ```js 49 | server.route({ 50 | method: 'GET', 51 | path: '/', 52 | handler: function(request, reply) { 53 | request.redis.get('homepage', function(err, result) { 54 | console.log(err, result); 55 | return reply(result); 56 | }); 57 | } 58 | }); 59 | ``` 60 | 61 | > If you want more usage examples, ask! :wink: 62 | 63 | ### Environment Variable 64 | 65 | If you want to use a Redis server from a 3rd Party Provider, e.g: Redis Cloud you will need to export an environment variable with the URL 66 | of the server e.g: 67 | 68 | ```sh 69 | export REDISCLOUD_URL=redis://rediscloud:password@redis-server.com 70 | ``` 71 | 72 | If you do not set a `REDISCLOUD_URL` the plugin will attempt to connect 73 | to redis on your localhost. 74 | 75 | 76 | ## Other Redis Providers? 77 | 78 | At *present* we are using [Redis Cloud](https://github.com/dwyl/learn-redis#which-redis-as-a-service-heroku-addon) 79 | for our Hapi apps because 80 | they have a great service at an affordable price. 81 | 82 | If you are planning on using another provider e.g. AWS ElastiCache (Redis), 83 | ***please let us know***! https://github.com/dwyl/redis-connection/issues 84 | 85 | ### Implementation Notes 86 | 87 | This package uses: [`redis-connection`](https://github.com/dwyl/redis-connection) 88 | which in turn exposes [`node_redis`](https://github.com/NodeRedis/node_redis) 89 | (*feature complete & high performance Redis client*) 90 | 91 | > Connecting to Redis Cloud is tested in: https://git.io/v6vTf 92 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var pkg = require('./package.json'); 2 | var run_once = false; // ensure we only attach the .on 'stop' event once 3 | var redisClient = require('redis-connection')(); // require & connect 4 | 5 | exports.register = function(server, options, next) { 6 | 7 | server.ext('onPreAuth', function (request, reply) { 8 | if(!run_once) { // close the connection when the server stops (e.g in tests) 9 | run_once = true; 10 | server.on('stop', function () { // only one server.on('stop') listener 11 | require('redis-connection').killall(); // close active redis connection 12 | server.log(['info', pkg.name], 'Redis Connection Closed'); 13 | }); 14 | } 15 | request.redis = redisClient; // assign once 16 | reply.continue() 17 | }); 18 | next(); 19 | }; 20 | 21 | exports.register.attributes = { 22 | pkg: pkg 23 | }; 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hapi-redis-connection", 3 | "version": "1.0.1", 4 | "devDependencies": { 5 | "decache": "^4.1.0", 6 | "env2": "^2.1.0", 7 | "hapi": "^14.0.0", 8 | "istanbul": "^0.4.4", 9 | "tap-spec": "^4.1.1", 10 | "tape": "^4.6.0" 11 | }, 12 | "dependencies": { 13 | "redis-connection": "^5.0.0" 14 | }, 15 | "author": "dwyl & friends", 16 | "license": "GPL-2.0", 17 | "repository": { 18 | "type": "git", 19 | "url": "git+https://github.com/dwyl/hapi-redis-connection.git" 20 | }, 21 | "scripts": { 22 | "quick": "./node_modules/tape/bin/tape ./test/*.js | node_modules/tap-spec/bin/cmd.js", 23 | "test": "istanbul cover ./node_modules/tape/bin/tape ./test/*.js | node_modules/tap-spec/bin/cmd.js", 24 | "coverage": "istanbul cover ./node_modules/tape/bin/tape ./test/*.js && istanbul check-coverage --statements 100 --functions 100 --lines 100 --branches 100", 25 | "report": "open coverage/lcov-report/index.html" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | var test = require('tape'); 2 | var dir = __dirname.split('/')[__dirname.split('/').length-1]; 3 | var file = dir + __filename.replace(__dirname, '') + ' -> '; 4 | 5 | var server = require('./server-example'); // test server which in turn loads our module 6 | 7 | test(file + 'GET / returns value of "Everything" ... ', function (t) { 8 | server.inject('/', function(response) { 9 | t.equal(response.statusCode, 200, '/ visited '); 10 | t.equal(response.payload, 'Everything is Awesome!'); 11 | t.end(); 12 | }); 13 | }); 14 | 15 | test(file + 'GET /incr increments a counter', function (t) { 16 | server.inject('/incr', function(response) { 17 | t.equal(response.statusCode, 200, '/incr >> ' + response.result); 18 | console.log('response.result:', response.result); 19 | t.ok(response.result > 0, '0 < ' + response.result); 20 | t.end(); 21 | }); 22 | }); 23 | 24 | // don't forget to stop your server: 25 | test.onFinish(function () { 26 | server.stop(function(){}); 27 | }) 28 | -------------------------------------------------------------------------------- /test/server-example.js: -------------------------------------------------------------------------------- 1 | var Hapi = require('hapi'); 2 | var assert = require('assert'); 3 | var server = new Hapi.Server({ debug: { request: ['error'] } }); 4 | 5 | server.connection({ port: process.env.PORT || 8000 }); 6 | 7 | server.register({ 8 | register: require('../index.js') 9 | }, function (err) { 10 | if (err) { 11 | console.error(err); 12 | throw err; 13 | } 14 | }); 15 | 16 | server.route({ 17 | method: '*', 18 | path: '/', 19 | handler: function(request, reply) { 20 | // first set the value of "Everything" key to "Awesome!" 21 | request.redis.set('Everything', 'Awesome!', function(err, result) { 22 | // get the value of "Everything" key and return it 23 | request.redis.get('Everything', function(err, result) { 24 | console.log('>> Everything is ' + result) 25 | return reply('Everything is ' + result); // https://youtu.be/StTqXEQ2l-Y 26 | }); 27 | }); 28 | } 29 | }); 30 | 31 | server.route({ 32 | method: 'GET', 33 | path: '/incr', 34 | handler: function(request, reply) { 35 | request.redis.incr('counter', function(err, result) { 36 | console.log('>> Counter ' + result) 37 | return reply(result); 38 | }); 39 | } 40 | }); 41 | 42 | server.start(function() { 43 | console.log('Visit: http://127.0.0.1:'+server.info.port); 44 | }); 45 | 46 | module.exports = server; 47 | --------------------------------------------------------------------------------