├── .gitignore ├── .sequelizerc ├── LICENSE ├── README.md ├── config ├── default.json ├── development.json ├── production.json └── test.json ├── controllers ├── index.js └── users.js ├── migrations └── 20141021121205-create-user.js ├── models ├── index.js └── user.js ├── package.json ├── plugins └── index.js ├── routes.js └── server.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io 2 | 3 | ### Node ### 4 | # Logs 5 | logs 6 | *.log 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | 13 | # Directory for instrumented libs generated by jscoverage/JSCover 14 | lib-cov 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 20 | .grunt 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # Commenting this out is preferred by some people, see 27 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 28 | node_modules 29 | 30 | # Users Environment Variables 31 | .lock-wscript 32 | -------------------------------------------------------------------------------- /.sequelizerc: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var config = require('config'); 3 | 4 | config.database.config = __filename; 5 | 6 | module.exports = config.database; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Miguel Andrade 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hapi Boilerplate 2 | ### *A Hapi boilerplate with Sequelize, Sequelize-CLI and node-config* 3 | 4 | Cool features in this boilerplate: 5 | 6 | - It's modular. Define your routes, plugins, models and controllers separately. 7 | - Uses [node-config](https://github.com/lorenwest/node-config). Define all your configuration properties hierarchically and according to your environment. 8 | - Models/ORM through [Sequelize](http://sequelizejs.com/) and [Sequelize-cli](https://github.com/sequelize/cli) with common configuration! Supports migrations. Read more about sequelize and Sequelize-cli. 9 | 10 | ## Directory structure ## 11 | 12 | The structure of the boilerplate and explanation follows: 13 | ```bash 14 | hapi-boilerplate 15 | ├── app.js # Application entry point run with "node app" 16 | ├── config 17 | │   ├── default.json # common config for all environments 18 | │   ├── development.json # config for development environments 19 | │   ├── production.json # config for production environments 20 | ├── controllers 21 | │   ├── index.js # file that requires all controllers into a hash 22 | │   └── users.js # an example controller. use it for inspiration. 23 | ├── migrations # migrations directory with an example migration. generated with "sequelize-cli" 24 | │   └── 20141021121205-create-user.js 25 | ├── models 26 | │   ├── index.js # generated with "sequelize init". requires all models. 27 | │   └── user.js # an example model. generated with "sequelize-cli model:create" 28 | ├── package.json 29 | ├── plugins 30 | │   └── index.js # register plugins. add your custom plugins in this folder as well. 31 | ├── README.md 32 | └── routes.js # define all the routes in this file. 33 | ``` 34 | 35 | ## Usage 36 | 37 | Just clone the repository: 38 | 39 | ```bash 40 | $ git clone https://github.com/miguelcobain/hapi-boilerplate.git 41 | ``` 42 | run 43 | 44 | ```bash 45 | $ npm install 46 | ``` 47 | 48 | and start coding. 49 | 50 | To run the application run `node app`. 51 | -------------------------------------------------------------------------------- /config/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "host":"0.0.0.0", 3 | "cors":true 4 | } 5 | -------------------------------------------------------------------------------- /config/development.json: -------------------------------------------------------------------------------- 1 | { 2 | "port":3000, 3 | "database" : { 4 | "username": "development_user", 5 | "password": "development_password", 6 | "database": "development_database", 7 | "host": "127.0.0.1", 8 | "dialect": "postgres" 9 | } 10 | } -------------------------------------------------------------------------------- /config/production.json: -------------------------------------------------------------------------------- 1 | { 2 | "port":80, 3 | "database" : { 4 | "username": "production_user", 5 | "password": "production_password", 6 | "database": "production_database", 7 | "host": "127.0.0.1", 8 | "dialect": "postgres" 9 | } 10 | } -------------------------------------------------------------------------------- /config/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "port":3000, 3 | "database" : { 4 | "username": "test_user", 5 | "password": "test_password", 6 | "database": "test_database", 7 | "dialect": "sqlite" 8 | } 9 | } -------------------------------------------------------------------------------- /controllers/index.js: -------------------------------------------------------------------------------- 1 | var requireDirectory = require('require-directory'); 2 | module.exports = requireDirectory(module); -------------------------------------------------------------------------------- /controllers/users.js: -------------------------------------------------------------------------------- 1 | var models = require('../models'); 2 | 3 | module.exports = { 4 | get:function (request, reply) { 5 | return models.User.findAll(); 6 | }, 7 | salute:function (request, reply) { 8 | return 'Hello, ' + encodeURIComponent(request.params.name) + '!'; 9 | } 10 | }; -------------------------------------------------------------------------------- /migrations/20141021121205-create-user.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //generated by sequelize-cli 4 | module.exports = { 5 | up: function(migration, DataTypes, done) { 6 | migration.createTable("Users", { 7 | id: { 8 | allowNull: false, 9 | autoIncrement: true, 10 | primaryKey: true, 11 | type: DataTypes.INTEGER 12 | }, 13 | firstname: { 14 | type: DataTypes.STRING 15 | }, 16 | lastname: { 17 | type: DataTypes.STRING 18 | }, 19 | username: { 20 | type: DataTypes.STRING 21 | }, 22 | password: { 23 | type: DataTypes.STRING 24 | }, 25 | createdAt: { 26 | allowNull: false, 27 | type: DataTypes.DATE 28 | }, 29 | updatedAt: { 30 | allowNull: false, 31 | type: DataTypes.DATE 32 | } 33 | }).done(done); 34 | }, 35 | down: function(migration, DataTypes, done) { 36 | migration.dropTable("Users").done(done); 37 | } 38 | }; -------------------------------------------------------------------------------- /models/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var fs = require("fs"); 4 | var path = require("path"); 5 | var Sequelize = require("sequelize"); 6 | var config = require("config").database; 7 | var sequelize = new Sequelize(config.database, config.username, config.password, config); 8 | var db = {}; 9 | 10 | fs 11 | .readdirSync(__dirname) 12 | .filter(function(file) { 13 | return (file.indexOf(".") !== 0) && (file !== "index.js"); 14 | }) 15 | .forEach(function(file) { 16 | var model = sequelize["import"](path.join(__dirname, file)); 17 | db[model.name] = model; 18 | }); 19 | 20 | Object.keys(db).forEach(function(modelName) { 21 | if ("associate" in db[modelName]) { 22 | db[modelName].associate(db); 23 | } 24 | }); 25 | 26 | db.sequelize = sequelize; 27 | db.Sequelize = Sequelize; 28 | 29 | module.exports = db; 30 | -------------------------------------------------------------------------------- /models/user.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = function(sequelize, DataTypes) { 4 | var User = sequelize.define("User", { 5 | firstname: DataTypes.STRING, 6 | lastname: DataTypes.STRING, 7 | username: DataTypes.STRING, 8 | password: DataTypes.STRING 9 | }, { 10 | classMethods: { 11 | associate: function(models) { 12 | // associations can be defined here 13 | } 14 | } 15 | }); 16 | 17 | return User; 18 | }; 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hapi-boilerplate", 3 | "version": "0.0.4", 4 | "description": "A Hapi boilerplate with Sequelize, Sequelize-CLI and node-config", 5 | "main": "server.js", 6 | "author": "miguelcobain ", 7 | "license": "ISC", 8 | "keywords": [ 9 | "hapi", 10 | "node", 11 | "boilerplate", 12 | "sequelize" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/miguelcobain/hapi-boilerplate" 17 | }, 18 | "bugs": { 19 | "url": "https://github.com/miguelcobain/hapi-boilerplate/issues" 20 | }, 21 | "dependencies": { 22 | "boom": "^5.2.0", 23 | "config": "^1.29.2", 24 | "good": "^7.3.0", 25 | "good-console": "^6.4.1", 26 | "hapi": "^17.2.0", 27 | "pg": "^7.4.1", 28 | "require-directory": "^2.1.1", 29 | "sequelize": "^4.4.2" 30 | }, 31 | "devDependencies": { 32 | "lab": "^14.3.2", 33 | "sqlite3": "^3.1.13" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /plugins/index.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | //set up good to log every kind of event. Change according to your needs. 3 | { 4 | register:require('good'), 5 | options:{ 6 | reporters: [{ 7 | reporter: require('good-console'), 8 | args:[{ log: '*', request: '*', ops: '*', error: '*' }] 9 | }] 10 | } 11 | } 12 | //require additional plugins here 13 | ]; 14 | -------------------------------------------------------------------------------- /routes.js: -------------------------------------------------------------------------------- 1 | var controllers = require('./controllers'); 2 | 3 | module.exports = [ 4 | { 5 | method: 'GET', 6 | path: '/users', 7 | handler: controllers.users.get 8 | }, 9 | { 10 | method: 'GET', 11 | path: '/salute/{name}', 12 | handler: controllers.users.salute 13 | } 14 | ]; 15 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Hapi = require('hapi'); 4 | 5 | var path = require('path'); 6 | var settings = require('config'); 7 | 8 | var routes = require('./routes'); 9 | var plugins = require('./plugins'); 10 | var models = require('./models'); 11 | 12 | const internals = { 13 | templatePath: '.' 14 | }; 15 | 16 | const server = new Hapi.Server({ 17 | host:settings.host, 18 | port: settings.port 19 | }); 20 | 21 | // server.connection({port:settings.port, host:settings.host}); 22 | 23 | // Export the server to be required elsewhere. 24 | 25 | var initDb = function(cb){ 26 | var sequelize = models.sequelize; 27 | 28 | //Test if we're in a sqlite memory database. we may need to run migrations. 29 | if(sequelize.getDialect()==='sqlite' && 30 | (!sequelize.options.storage || sequelize.options.storage === ':memory:')){ 31 | sequelize.getMigrator({ 32 | path: process.cwd() + '/migrations', 33 | }).migrate().success(function(){ 34 | // The migrations have been executed! 35 | cb(); 36 | }); 37 | } else { 38 | cb(); 39 | } 40 | }; 41 | 42 | server.route(routes); 43 | 44 | 45 | internals.main = async () => { 46 | await server.start(); 47 | initDb(()=>{ 48 | console.log('Server is running at ' + server.info.uri); 49 | }); 50 | 51 | } 52 | 53 | internals.main(); 54 | 55 | module.exports = server; 56 | --------------------------------------------------------------------------------