Hapi(ness) v17
Node 8 hit LTS status recently and now we have full async/await support (yay!) on a stable Node version. This also means that a lot of JS libraries and frameworks have the oppurtunity to do code cleanups / rewrites to give us simpler APIs and faster / simpler code. KoaJS was the first to get on this train and now HapiJS also joined the party and released a big upgrade with v17.
In this short post we will look at setting up basic authentication and logging functionality with hapi v17 (since I usually need this for all projects). First thing of note is that since v17 is a major re-write, a lot of plugins for hapi have / had to be re-written as well. Two plugins that I usually rely on hapi-auth-jwt-2 and good right now do not work with v17. However, with hapi-auth-jwt2 plugin there is already a PR so it is just a matter of forking it for now and applying the PR. For logging we will use hapi-pino. So the basic hapi v17 server setup looks like -
'use strict';
const Hapi = require('hapi');const Config = require('config');const HapiAuthJWT = require('hapi-auth-jwt2');const HapiPino = require('hapi-pino');
const Routes = require('./lib/routes/');const Token = require('./lib/services/token');
// Create a server with a host and portconst server = new Hapi.Server({ port: Config.get('api.port'), routes: { cors: Config.get('api.cors') }});
const init = async () => {
// Register plugins await server.register(HapiAuthJWT); await server.register(HapiPino);
// Auth setup server.auth.strategy('jwt', 'jwt',{ key: Config.get('token.secret'), validate: Token.validate, verifyOptions: { algorithms: ['HS256'] } }); server.auth.default('jwt');
// Routes server.route(Routes);
await server.start(); return server;};
init() .catch((err) => console.error(err));
module.exports = server;
Sample routes -
const PingController = require('../controllers/ping_controller');const MessagesController = require('../controllers/messages_controller');const TokenController = require('../controllers/token_controller');const UsersController = require('../controllers/users_controller');const SharedMessagesController = require('../controllers/shared_messages_controller');
const routes = [ { method: 'GET', path: '/ping', options: { auth: false }, handler: PingController.show }, { method: 'POST', path: '/token', options: { auth: false }, handler: TokenController.create }, { method: 'GET', path: '/me', options: { auth: 'jwt' }, handler: UsersController.show }, { method: 'GET', path: '/messages', options: { auth: 'jwt' }, handler: MessagesController.index }, { method: 'GET', path: '/messages/{id}', options: { auth: 'jwt' }, handler: MessagesController.show }, { method: 'DELETE',path: '/messages/{id}', options: { auth: 'jwt' }, handler: MessagesController.delete }, { method: 'PUT', path: '/messages/{id}', options: { auth: 'jwt' }, handler: MessagesController.update }, { method: 'POST', path: '/messages', options: { auth: false }, handler: MessagesController.create }, { method: 'GET', path: '/sharedMessages',options: { auth: false }, handler: SharedMessagesController.index }];
module.exports = routes;
And a sample handler -
class Ping {
show(request, h) {
return { pong: true }; }
}
module.exports = new Ping();
That’s it, we are all set with a simple hapi v17 server with JWT authentication & logging and for sure it is simpler and faster.