This is a review of the Hapi 2.0 functionality unveiled last Monday, Jan 27, 2014 at &yet. The event was live streamed so I was able to watch and take notes. Eran Hammer @eranhammer, a Walmart labs engineer and lead developer for Hapi shared a top to bottom feature discussion including the new changes for version 2. Eran’s Slides
My goal with this podcast is to mention some of the key changes with Hapi 2 and how you would leverage them in your code.
This review and Eran’s presentation are done such that you do not need have a familiarity with Hapi to get value, new users should come away with some understanding of Hapi and how it can be useful for building robust web applications.
Episode Info
- Episode: CW 002
- Published: February 1st, 2014
- Tags: nodejs, hapijs
- Duration: 21:46
Episode Notes
Background
- show notes http://codewinds.com/podcast/002.html
- I have a link to the original live stream, the content starts at about 24 minutes in, so the URL in the show notes jumps directly to that spot.
- Hapi is the awesome open source web framework created by Walmart Labs.
- The Hapi framework grew out of years of development first at Yahoo as Sled, later renamed Postmile, then at Walmart Labs.
- Initially Eran tried to build on Express a popular web framework, but found issues with plugin order, undocumented dependencies, fragility with large team use.
- Hapi was developed by Walmart Labs for their mobile division
- Hapi is built as a scalable web framework that they could use to evolve their system over time.
- Initiallly used to reverse proxy or pass through requests to their existing backend written in java or other languages.
- Then decorate, batch, and begin to replace legacy code with new code in Node.js
- It ran 100% of their mobile traffic starting with Black Friday and proved its stability running at about 1-2% cpu on 50 servers throughout the highest load. Lasagna graphs flatlines for cpu and memory use
- Walmart starting to replace more of its legacy code with Hapi and even now part of walmart.com
- Hapi has great REST API support as well as infrastructure for building web apps or even serving static content
- Just configure the routes and you are ready, no extra plugins are necessary for the most common functionality
- Liked that Eran provides some quick commentary about features and how they evolved
- Hapi 2.0 isn’t a massive increase in new functionality, in fact it is more about taking out the cruft, eliminating the redundant ways to do things. Names that evolved over time, picking the best and cleaning up the others.
- This strategy shows the wisdom and experience of its architect, to resi the urge to add features by first solidifying the base.
Routes, Caching, State
- Route
handler(request, reply)
signature changed server.route({})
, can keep routes in one place while config and handler in separate module. validation is configurable, state (cookies)server.table()
gives you the active routing table- Hapi is a configuration centric framework, set js properties, then it tries to stay out of your way.
- Hapi is written so the meat of your web application can stay pure, you don’t have to deal with the HTTP mechanisms unless you need to for a special case. This leads to clean code which is more focused on your business logic and less on how to deliver via HTTP.
- Helpers can abstract out functionality used in many places like looking up a user profile or users shopping cart
- Caching is changed in 2.0, dropping support for full page caching. You can still configure the client cache headers and expiry but the team removed the page cache since they didn’t want to have a half baked solution, one that didn’t handle all the variety of use cases.
- They still have great support for helper caching which is more straight forward.
- Eran said they will possibly add page caching back in later or I’d expect there to be a basic plugin which provides a basic page cache solving the simple use cases.
- Route prerequesites clean up async handling, can specify arrays for parallel followed by single tasks which are processed serially and any combintion.
handler.bind
can be used to share state using object methodsreply().hold()
, later callingsend()
when ready- Cookie ttl configuration can now be done in a central location cleaninpu up the route config
- Exentensive cookie functionality - automatically encoding in base64 json or even using encryption, hashing, and expiration with Eran’s Iron container
Plugins
- Plugins are a cornerstone of Hapi. These differ from something like Express in that plugins are just groupings of server functionality that can be mixed together into servers. You can organize a feature’s functionality, its routes, its configuration, and dependencies. This lives like a normal node.js package and only needs a register method to use with Hapi. These can be developed, versioned separately, mixed in to the server.
- Hapi ensures that once they are all registered that the routes are all valid and nothing conflicts, its a large team’s dream. Easy to test new veerions.
- Plugins can do everything you can do with the server, add routes, helpers, etc.
plugin.composer
or command line option to hapi allows you to build a server with simply a package.json and a config.json specifying plugins to use.- If you couple plugins along with Hapi’s Confidence module you can have one setup which can provide server config for all your various environments.
- The Confidence module provides dynamic configs which can be used for server environments or even runtime use for A/B testing
- Plugin cache is now scoped so its data won’t collide with other plugins
Authorization
- Authorization is now properly extracted into schemes and strategies, basic auth, hawk, etc. It is much easier to setup authentication and you have options to make authentication required and optional.
- Hapi has defined life cycle extension points at which you can register to have your code called during request life cycle. For instance you could hook in at the beginning of the request, before auth, after auth, before response, etc.
- These extensions can specify dependencies and whether they need to go before or after others.
- One change to how the signature for these extensions is that they now have two params (request and reply) just like handlers. You can call the reply(null) to continue response unchanged. Website docs don’t reflect this yet, so look at the code or tests.
- You can now do additional things for streamed responses in your extensions like set headers as well as peek into the packets being sent back
Ops
- New ops functionality
- Can have server load and memory use logged for easy server health montioring
- Configure max input size, timeouts for client and server
- You can register tail methods which run after a response has been sent
server.inject
allows you to use the hapi stack without going through the network stack, great for testing and even for production use if you need to call back in like with OAuth 2.0- There is now a simulate property for simulating connection close issues
Postmile example app
- github.com/hueniverse/postmile - large sample app which has been upgraded to Hapi 2.0. It is a collaborative list making tool using hapi 2.0 and Mongo.
Major breaking changes
handler(request, reply)
, extensions have similar signature- methods that had many aliases are now simplified like server.route
- page caching removed for now
- route prerequisites now use arrays to designate parallel tasks, and you can mix serial and parallel
- read up on the new auth configuration and mechanisms
- https://github.com/spumko/hapi/issues/1178 - github issue with all the Hapi 2.0 breaking changes
Resources
- http://hapijs.com - main site, docs being added for 2.0
- https://github.com/spumko/hapi - git repo for Hapi
- https://github.com/spumko/hapi/issues/1178 - github issue with all the Hapi 2.0 breaking changes
- https://github.com/spumko - extracted Hapi functionality for use with Hapi or separately
- https://dl.dropboxusercontent.com/u/52139546/hapi%20yet%3F.pdf - hapi-yet-slides with lots of code examples which Eran Hammer used for his live stream
- http://www.youtube.com/watch?v=B3u0XkbhleA&t=1461 Eran Hammer Hapi Yet (Hapi 2.0) live stream at &yet, link jumps directly to 24 min where talk starts
- https://github.com/hueniverse/postmile Eran Hammer’s sizeable hapi example using many of the Hapi features. Postmile is a collaborative list making tool using hapi 2.0 and mongo.
- https://github.com/poeticninja/hapi-ninja - Saul Maddox’s @poeticninja boilerplate Hapi server example Node.js, Hapi 2.0, Swig templates, Gulp task runner
- Follow http://codewinds.com/ blog and podcast for continuing coverage
Summary
So in summary, Hapi 2.0 is a well thought out release which cleans up and solidifies the codebase while adding some key functionality that can be built on.
With Walmart putting this framework through the paces and other companies following in its footsteps like the company I am consulting to MasterCard, this framework has evolved with clarity, performance, team usability, and has great deploy and ops support.
Furthermore, Eran and his team have proved that Hapi can handle Black Friday load with ultimate grace, and this new version solidifies its position among Node web frameworks.
So I encourage you to check out Hapi, and let me know what you think. Head over to codewinds.com and leave me a comment or send me a tweet.