This Boilerplate is ready to use pack having very exciting feature of HapiJs and MongooseJs.
This Boilerplate having some of common plugin which can be used as per required.
This Boilerplate will give you a quick start to your Node Application Server with HapiJs.
We are Hapi to release this exciting version to build your Node app on Hapi-Api-Boilerplate.
It's by default gives you the ToDoApplication
API's. It will help you to understand and build your own API's.
When run this boilerplate first time, it will ask for auth key of GMail notification integration and send you email on application start. Update the Bootstrap.js
Test
Task.
- Open link https://console.developers.google.com/flows/enableapi?apiid=gmail
- Use this wizard to create or select a project in the Google Developers Console and automatically turn on the API.
- Click Continue, then Go to credentials.
- At the top of the page, select the OAuth consent screen tab. Select an Email address, enter a Product name if not already set, and click the Save button.
- Select the Credentials tab, click the Create credentials button and select OAuth client ID.
- Select the application type Other, enter the any name "gmail-node-app", and click the Create button.
- Click OK to dismiss the resulting dialog.
- Click the file_download (Download JSON) button to the right of the client ID.
- Copy the file data from from Downloaded JSON and update the
/config/Config.json
file.
Try Now To-Do-List Application Api
NodeJs v4.x
and above required.MongoDB Server 3.2.x
and above required.
This library is available for Node v4 and above. See the installation steps below:
$ git clone git@github.com:kashishgupta1990/hapi-api.git
$ npm install
$ node app.js (By Default you can see server running on Address http://localhost:9999)
Execute this command inside your project root directory. This will remove unwanted files which was use for ToDoApplication
.
sh reset.sh
- api
- CreateFolder(auth)
- FileName.route.js (login.route.js)
- FileName.service.js (login.service.js)
- FileName.spec.js (login.spec.js)
- CreateFolder (You can make sub-nesting folder..)
- FileName.route.js (So on ..)
- FileName.service.js (So on ..)
- FileName.spec.js (So on ..)
- CreateFolder (So on ..)
- FileName.route.js (So on ..)
- FileName.service.js (So on ..)
- FileName.spec.js (So on ..)
- CreateFolder(auth)
- modules (It broadly contains the custom modules)
- coreComponents (It has all the main functionality of the core architecture)
- bootstrap.js (When application gets up the task present inside get executed.)
- globalEventRegister.js (Add the events which need to access from anywhere from the codebase.)
- globalMethod.js (We can add application level global methods which can be used directly eg. requireFile("FileName"))
- hapiPlugin.js (Add hapi plugins here.)
- validateEnv.js (Use this file to add environment variable validation.)
- customPlugin (Add hapi custom plugin here)
- globalEvent (Add global events here)
- email.js
- notification.js (It is just a sample file. Showing the file structure and usage.)
- So on...
- coreComponents (It has all the main functionality of the core architecture)
- db
- modules
- ToDoList.js (It is
M
fromMVC
framework. Containing the ToDoApp model.) - User.js (It contain the User model which interact with mongodb.)
- ToDoList.js (It is
- schema
- User.js (Containing ToDoApplication User Schema)
- Sample.js (Its is just a sample file. Showing the file structure and usage.)
- modules
- node_modules
- contains all the dependency ...
- client (Contain all public folder)
- index.html
- css
- So on..
- app.js (main file of the project)
Bootstrap.js
is a task runner file which executes on start of application according to appropriate environment settings.
See below given snippet for quick start to create task named Test
and run on development
environment
module.exports = function (environment, callback) {
//Add your task name here
var env = {
"development": [Test]
};
//Create your task like function
function Test(callback) {
log.cool('Test Task Runner');
callback(null, 'Test Task Runner')
}
};
It contains all the application level configuration variables. Use .env file by process.env.{your-variable-name}
as global variable.
#Server Variables
ENV_NAME=DEVELOPMENT
PORT=9999
ALLOW_CROSS_DOMAIN=true
JWT_KEY=NeverShareYourSecretNeverShareYourSecret
#Mongodb Variables
MONGODB_URL=mongodb://localhost:27017/boilerplate
MONGODB_POOL_SIZE=2
MONGODB_RECONNECT_DELAY=10000
#GMail Variables
GMAIL_CLIENT_ID=677725446467-6li25pcqgkcllsoh6f6dijcvse64n9pf.apps.googleusercontent.com
GMAIL_PROJECT_ID=clean-node-119606
GMAIL_AUTH_URL=https://accounts.google.com/o/oauth2/auth
GMAIL_TOKEN_URL=https://accounts.google.com/o/oauth2/token
GMAIL_AUTH_PROVIDER_X509_CERT_URL=https://www.googleapis.com/oauth2/v1/certs
GMAIL_CLIENT_SECRET=F7DvoA_ZrNfa65GnU2zQBgw7
GMAIL_REDIRECT_URIS_INDEX1=urn:ietf:wg:oauth:2.0:oob
GMAIL_REDIRECT_URIS_INDEX2=http://localhost
db/schema
is a home for all mongoose domain. You just have to create file like User.js
, define mongoose schema into file, that's all.
You can access your mongoose modal form any where in boilerplate (routes, bootstarp files) by Modal
object.
Examples are given below:
Define Sample Domain
in /db/schema/Sample.js
"use strict";
//Define Sample Schema
//Refer: http://mongoosejs.com/docs/schematypes.html
var sample = {
schema: {
id: Number,
sampleData: String,
sampleItem: String
},
modelMethods: [
{
name: 'M1',
action: ()=> {
console.log('I am sample method M1');
}
},
{
name: 'M2',
action: ()=> {
console.log('I am sample method M2');
}
}
]
};
// Schema
module.exports = sample;
Use Define Sample Module
in /db/modules/sample.js
'use strict';
module.exports = {
saveSample: (callback)=> {
// Creating Sample data object
var sData = new Model.Sample({
sampleData:'s1',
sampleItem:'s2'
});
// Calling model method
sData.M1();
// Save into database
sData.save(callback);
},
getSample: (callback)=> {
Model.Sample.find({},callback);
}
};
##How to define Routes##
api
is a folder where we can define routes. Create folder in side api
folder or you can directly create file with any name we want. File should follow the *.route.js
notation. Here *
will be replaced by any filename
.
"use strict";
var Joi = require('joi');
//Routs Lists
module.exports = [
{
path: '/sample/test/special',
method: 'GET',
config: {
description: 'Get Test-1',
notes: 'Yes, I am doing testing',
tags: ['api'],
handler: (request, reply)=> {
reply({status: 'my ecma6 special reply'});
}
}
},
{
path: '/sample/test/test2',
method: ['GET', 'POST'],
config: {
description: 'Get Test-2',
notes: 'Yes, I am doing testing',
tags: ['api'],
handler: function (request, reply) {
reply({status: 'I am Test-2 API'});
}
}
},
{
//Here you can add more routs (Hapi Syntax)
//Refer: http://hapijs.com/tutorials/routing
}
];
To authenticate the API's
here we have used [JSON Web Token]: https://github.com/dwyl/hapi-auth-jwt2, which help us to secure our routes just by adding one field in route config:{}
object.
which is auth:"jwt"
to enable the secure route and auth:false
to disable the routes. Refer the File: api/toDoList/addTask.route.js
.
- How to create
User Token
at the time of login First require the packagenpm install jsonwebtoken
var JWT = require('jsonwebtoken');
- Sign the Token with same secret key available in
/config/Config.json
. Field:jwt:'your-secret-key'
let token = JWT.sign(userData, global._APP_CONFIG.jwt.key);
- Setting this key in Response data and response header.
reply({
status:true,
message:'successfully login',
data:{
email:data.email,
token:token
}
}).header("Authorization", token);
- All the future request raise by client containing with
authorization
header can accessauthenticated
API's
. Try this interminal
curl -X GET --header 'Accept: application/json' --header 'authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Imthc2hpc2hndXB0YTE5OTBAeWFob28uY29tIiwiaWF0IjoxNDY4OTI2MDY3fQ.FNtiiSkQDSvfG4KZfB6f7MMMjlJ2lNTpLpMYJz83Y1o' 'http://localhost:9999/api/v1/todolist'
-
Access Token (decoded) Data inside Route Handler Token generated at the time of
login
should be available in the request header with therequest.tokenData
This token contains the user data or what ever you want to save at the time of login. Referapi/auth/login.route.js
-
Generate & save token Login API Example
var JWT = require('jsonwebtoken');
{
path: '/api/v1/auth/login',
method: ['POST'],
config: {
description: 'Login Here',
notes: 'Do login here',
tags: ['api'],
auth: false, // This is use for open route
validate:{
payload:{
email:Joi.string().email().required(),
password:Joi.string().min(8).max(16).required()
}
},
plugins: {
'hapi-swagger': {
responses: {
'200': {
'description': 'Success',
'schema': Joi.object({
status:true,
message:'Successfully Login'
}).label('Result')
},
'400': {'description': 'Bad Request'}
},
payloadType: 'json'
}
},
handler: function (request, reply) {
var dbPayload = {
email: request.payload.email,
password: request.payload.password
};
dao.user.validateUser(dbPayload, (err, data)=>{
if(err){
reply(err);
}else{
if(data){
let userData = {
email:data.email
};
let token = JWT.sign(userData, global._APP_CONFIG.jwt.key);
reply({
status:true,
message:'successfully login',
data:{
email:data.email,
token:token
}
}).header("Authorization", token);
}else{
reply({
status:false,
message:'Invalid User or Password',
data:{}
});
}
}
});
}
}
}
- Access Token Data API
Refer File:
/api/toDoList/addTask.route.js
{
path: '/api/v1/todolist',
method: ['POST'],
config: {
description: 'Add new ToDo Task',
notes: 'Add new ToDo Task',
tags: ['api'],
validate: {
payload: {
description: Joi.string().required()
},
headers: Joi.object({
'authorization': Joi.string().required()
}).unknown()
},
auth: 'jwt', // This is use for auth routes
handler: (request, reply)=> {
// Access Secure Token User Data
console.log('Token Data: ',request.tokenData);
}
}
}
We support Heroku
cloud platform as a service (PaaS). It's very easy to deploy on Heroku
server just update your application config.json
file with appropriate environment name, server, cookies and database settings. Finally push your code to heroku master
branch rest will automatically done by Heroku
.
We support Docker
Container as a service (CaaS). It's very easy to build the Hapi Api Boilerplate
docker image with updated codebase and run the container on any type production environment.
To create docker image we need to run simple docker command docker build -t kashishgupta1990/hapiapi .
. Here kashishgupta1990/hapiapi
is the name of the image you can the change the image name on your own. This command use the Dockerfile
present in root
folder of the project and build the Docker Image
of current project state.
docker build -t kashishgupta1990/hapiapi .
To test the newly created docker image, we need to execute the command docker run --name "hapiapi" -p 9999:9999 kashishgupta1990/hapiapitest
. This will create docker container
and you can test your Docker Image
via just check the server listening on PORT: 9999
. If YES
then your did well :)
docker run --name "hapiapitest" -p 9999:9999 kashishgupta1990/hapiapitest
Run the command to execute on background docker run -d --name "hapiapi" -p 9999:9999 kashishgupta1990/hapiapitest
docker run -d --name "hapiapiprod" -p 9999:9999 kashishgupta1990/hapiapitest
- Check the existing container running on system
docker ps -a
- Select the CONTAINER ID / NAMES (look like -> aea8bf1d2562) and copy it. Run the following command. It will return you container terminal.
docker exec -it hapiapi /bin/bash
docker exec -it aea8bf1d2562 /bin/bash
- Type command:
pm2 logs
pm2 logs
Just open an issue in case found any bug(There is always a scope of improvement). We are always open for suggestion / issue / add new feature request. Fork and start creating pull request. :-)