Yet another hapi boilerplate for a RESTFul server. Opinionated.
Using Node Native Promises for async handling, standardjs for linting, and grouping files by resource (for the API).
Leverages the hapi ecosystem to a great extent:
- Lab and Code for testing
- Glue for server configuration and plugin registration
- hapi-auth-cookie for authentication
- Hapi builtin authorization via scope (see route options in Hapi API docs for details)
- Confidence for config management
- Crumb for CSRF prevention
- Joi for validation
- Boom for http error responses
- Good for logging
- Lout (+ Vision & Inert) for automatic documentation
Uses a fake json database in order to be DB agnostic, but it can easily be used with any DB, with small changes.
This boilerplate has authentication and authorization setup, and user management api routes, for both demo purposes and to bootstrap an application easily.
Hapijs Plugins are used to organize and modularize code. General purpose plugins
go into lib/
directory. API plugins go into api/{resource}
directories.
Plugins are wiredeup using Glue. All plugin loading logic is into lib/manifest.js
file.
For API resources, the directory contains 3 files: index.js
, handlers.js
and
model.js
Example:
api
|- users
|- index.js
|- handlers.js
|- model.js
index.js
is basically a router file, were plugin is declared and routes are
registered into server.
The router handlers are declared in handlers.js
file. This file exports a
function that receives as argument the options
parameter from plugin
registration. This serves both to pass global parameters (such as db connections)
to handlers and to do dependency injection in tests. An object with all handlers
is returned. The handlers signature is allways (request, reply)
.
const Handlers = require('./handlers')
const options = {
db: someDBStub
}
let handlers = Handlers(options)
console.log('handlers', handlers)
// {
// create: function (request, reply) {...},
// read: function (request, reply) {...},
// ...
// }
The handlers interact with the Model, where businness logic should be encapsulated, such as validations (other than payload validation, which is done at router level), DB operations and such likes. The model file also exports a function which receives the options object passed to Handlers function, and returns an object with all model operations, such as basic CRUD functionality.
All model function return promises.
The model also returns a blueprint object, used for payload validation in router.
To keep this boilerplate DB agnostic, an in-memory db is used. This is not intended for production use, but rather to set a basic interface for the model file, which should be adapted acording to the DB used in a real project.
- Clone repo
- Run
npm install
- Setup environment variables in a .env file
(see dotenv). The following environment
varibles must be set:
- NODE_ENV: should be either
test
,dev
,staging
orprod
- COOKIE_SECRET: the secret used to protect the cookie data used in
authentication (required only for
prod
environment)
- NODE_ENV: should be either
- Run
npm run
Feel free to clone and make the changes you want. If you want to commit them back to this repo, please ensure that tests pass and coverage is > 95% (ideally 100%)
Many of the things implemented in this boilerplate where extracted from Hapijs University repository.
MIT License