Daniela Matos de Carvalho
Software Engineer @Dashlane, mother, photographer amateur, former @requirelx organiser, prev @YLDio, @zpx_interactive
Daniela Borges
hapijs/bossy lead maintainer, mentor
photography amateur
origami master
full-stack dev
ylder
@sericaia
var Hapi = require('hapi');
var config = {
dbConnection: 'mongodb://myvoodoapp',
drinks: ['capirinha', 'mojito', 'margarita']
};
var server = new Hapi.Server({
app: config
});
server.start();
var Hapi = require('hapi');
var config = {
dbConnection: 'mongodb://myvoodoapp',
drinks: ['capirinha', 'mojito', 'margarita']
};
var server = new Hapi.Server({
app: config
});
server.start();
accessible through
server.settings.app
var Hapi = require('hapi');
var server = new Hapi.Server();
server.connection({
host: 'localhost',
port: 8000
});
server.route({
method: 'GET',
path:'/api/mediterraneajs',
handler: function (request, reply) {
reply('Mediterranea JS...the best route to meet Barcelona!');
}
});
server.start();
index.js
var register = function (plugin, options, next) {
plugin.route({
method: 'GET',
path:'/api/mediterraneajs',
handler: function (request, reply) {
reply('Mediterranea JS...the best route to meet Barcelona!');
}
});
next();
};
register.attributes = {
name : 'mediterraneaApi',
version : '1.0.0' // I am confident!
}
module.exports = register;
mediterraneaApi.js
var Hapi = require('hapi');
var server = new Hapi.Server();
server.connection(...);
// Register the API
server.register( [ mediterraneaApi, (...) ] ,
function (err) {});
server.start();
index.js
source: http://projectzomboid.com/blog/wp-content/uploads/2014/08/BC_Keep_Calm_and_Stay_Lazy_2_copy-712x462.jpg
var mediterraneaApi = require('./mediterraneaApi.js');
server.register({register: mediterraneaApi}, {
routes: {
prefix: '/api'
}
}, function (err) {
});
The request object is created internally for each incoming request.
The request object methods and properties change throughout the request lifecycle.
we can modify each extension point using
server.ext(extension_point_event, method, [options])
server.ext('onRequest', function (request, reply) {
request.setUrl('/vodoo');
return reply.continue();
});
server.ext('onRequest', function (request, reply) {
request.setUrl('/vodoo');
return reply.continue();
});
server.route({
method: 'GET',
path: '/vodoo',
handler: function (request, reply) {
return reply("making vodoo interceptor @MediterraneaJS");
}
});
server.start();
verify route permissions
- may be specified by a strategy
set and authenticate payload
server.auth.strategy(name, scheme)
identify our specific strategy
general type of auth
var HapiAuthBasic = require('hapi-auth-basic');
//...
var validate = function (username, password, callback) {
//...
};
server.register(HapiAuthBasic, function (err) {
server.auth.strategy('simple', 'basic', { validateFunc: validate });
server.route({
method: 'GET',
path: '/',
config: {
auth: 'simple',
handler: function (request, reply) {
reply('hello, ' + request.auth.credentials.user);
}
}
});
});
uses hapi-auth-basic
defines 'basic' scheme
var HapiAuthBasic = require('hapi-auth-basic');
//...
var validate = function (username, password, callback) {
//...
};
server.register(HapiAuthBasic, function (err) {
server.auth.strategy('simple', 'basic', { validateFunc: validate });
server.route({
method: 'GET',
path: '/',
config: {
auth: 'simple',
handler: function (request, reply) {
reply('Welcome, ' + request.auth.credentials.user);
}
}
});
});
defines the strategy
var HapiAuthBasic = require('hapi-auth-basic');
//...
var validate = function (username, password, callback) {
//...
};
server.register(HapiAuthBasic, function (err) {
server.auth.strategy('simple', 'basic', { validateFunc: validate });
server.route({
method: 'GET',
path: '/',
config: {
auth: 'simple',
handler: function (request, reply) {
reply('hello, ' + request.auth.credentials.user);
}
}
});
});
sets auth = our strategy
server.auth.scheme('basic', scheme);
server.auth.strategy('vodoo', 'basic');
server.auth.default('vodoo');
hapi-auth-cookie
uses 'cookie' schema
bell
3rd party
uses 'bell' schema
server.auth.strategy('twitter', 'bell', {
provider: 'twitter',
password: 'encryption_password',
clientId: 'client_id',
clientSecret: 'client_secret'
});
plugin.route({
method: 'GET',
path:'/welcome/{name}',
handler: function (request, reply) {
var welcomeMsg = 'Welcome ' + request.params.name + "!\n";
welcomeMsg += 'Are you ' + request.query.mood + "?";
reply(welcomeMsg);
},
config: {
validate: {
params: {
name: Joi.string().required()
},
// ...
}
}
});
Validate params
plugin.route({
method: 'GET',
path:'/welcome/{name}',
handler: function (request, reply) {
var welcomeMsg = 'Welcome ' + request.params.name + "!\n";
welcomeMsg += 'Are you ' + request.query.mood + "?";
reply(welcomeMsg);
},
config: {
validate: {
// ...
query: {
mood: Joi.string().valid(["happy","sad"])
.default("happy")
}
}
}
});
Validate query
May contain an object or array of objects with actions
Actions 'terminate' with a reply(), and pass the result to the next step
var caipirinhaIngredients = function (request, reply) {
return reply('Cachaça, lime, and sugar');
};
var mojitoIngredients = function (request, reply) {
return reply('Mint leaves, limes, rum, sugar, and soda');
};
var partyDrinks = function (request, reply) {
return reply(request.pre.caipirinha + ' and ' + request.pre.mojito);
};
server.route({
method: 'GET',
path: '/party',
config: {
pre: [
[
/* capirinha and mojito executed in parallel */
{ method: caipirinhaIngredients, assign: 'caipirinha' },
{ method: mojitoIngredients, assign: 'mojito' }
],
{ method: partyDrinks, assign: 'drinks' },
],
handler: function (request, reply) {
return reply(request.pre.drinks);
}
}
});
between onPreHandler and onPostHandler we can change reply(), i.e we can change the response
uses the signature function(request, reply)
request object
reply interface
The response object contained in request.response may be modified
always called
The response object contained in request.response may be modified
may emit 'request-error' event
finally returns data to client!
request.tail([name])
Returns a tail function which must be called when the tail activity is completed
server emits one 'tail' event when all tails are completed
hapi-auth-basic/cookie/bell
joi
*
*
* always called
micro-services plugin
hapijs/bossy lead maintainer, mentor
photography amateur
origami master
full-stack dev
ylder
@sericaia
By Daniela Matos de Carvalho
Software Engineer @Dashlane, mother, photographer amateur, former @requirelx organiser, prev @YLDio, @zpx_interactive