Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

15.0.0 Release Notes #3323

hueniverse opened this issue Aug 26, 2016 · 0 comments

15.0.0 Release Notes #3323

hueniverse opened this issue Aug 26, 2016 · 0 comments


Copy link

@hueniverse hueniverse commented Aug 26, 2016


hapi v15.0.0 is a medium size release focused on refactoring the server events facilities, security enhancements, and improved extensibility. The events improvement introduce a whole new set of features to filter existing events, as well as build application specific events using a new application message bus using the podium module.

  • Upgrade time: medium - a couple of hours to a day or two for most users
  • Complexity: medium - requires following the list of changes to verifying their impact
  • Risk: medium - changes to how events are emitted and changes in some defaults require testing
  • Dependencies: low - most existing plugins will work as-is


The v15.0.0 major release is sponsored by Benjamin Flesch and StriveWire. StriveWire is currently hiring full stack developers in Hamburg, Germany.

Breaking Changes

  • Replace node's built-in EventEmitter with podium.
  • Change default cookies to use the HttpOnly, Secure, and SameSite=Strict properties by default to any cookie set via the state() method.
  • Error when reply() is called with a third argument when not used in the authenticate() authentication strategy method.
  • Disable request.getLog() by default, prevent memory allocation when the request logs are not needed.
  • Force server.register() to always return the callback after the next tick.
  • Override route validation rules when defined at the route level. The last configuration is the only one used for each route, ignoring any connection or server level defaults.
  • Error when reply.continue() is called with an argument when not used in the authenticate() authentication strategy method unless called in extension methods after the handler is called.

New Features

  • server.emit(criteria, data, [callback]) and server.event(events) methods for application events.
  • server.on(criteria, listener) and server.once(criteria, listener) support for new advanced subscription criteria (tags filter, channels, update clone, data spread, and performance optimizations for costly events without listeners).
  • Support for the new cookie SameSite property.
  • server.encoder(encoding, encoder) and server.decoder(encoding, decoder) for custom content encoding support.
  • Expose route authorization access logic via route.auth.access().
  • Expose authorization scope errors.
  • Support failAction in response validation, similar to request validation.
  • reply().message() to set the HTTP response message.
  • Control the logging of request-level events.
  • Control the input validation of server.inject() requests for improved performance.
  • Extensions 'onPostHandler' and 'onPreResponse' can override the response using reply.continue() without ending the request lifecycle.

Bug fixes

  • Always set 'Vary' header except when compression is disabled or not applicable to the response type.
  • Fix 'Content-Type' parameters separator.
  • Better handing for rejection errors in promises.
  • Rely on node's header validation instead of a more limited rule in hapi.
  • Prevent merging of route validation rules to prevent unexpected results.
  • Ensure 206 responses (ranged) are not compressed to avoid corrupted responses.
  • Improve performance of server.start() and server.stop() when server has multiple connections (replace serial to parallel processing).
  • Set route validation bind context for custom validation functions.
  • Ensure HEAD responses include all the GET headers.

Updated dependencies

  • statehood from v4.0.3 to v5.0.0
  • boom from v3.2.2 to v4.0.0
  • iron from v4.0.2 to v4.0.3
  • ammo from v2.0.1 to v2.0.2
  • call from v3.0.2 to v3.0.3
  • wreck from v8.0.1 to v9.0.0
  • subtext from v4.0.5 to v4.2.0
  • shot from v3.1.1 to v3.3.1

Migration Checklist


The event emitters used by the request, response, server, and connection interfaces have been replaced to use the new podium module instead of node's built-in EventEmitter. This was done to provide the framework full control over the events interface and support an array of new features.

The following EventEmitter methods and properties are no longer supported:

  • newListener and removeListener events
  • listenerCount()
  • defaultMaxListeners
  • eventNames()
  • getMaxListeners()
  • listenerCount()
  • listeners()
  • prependListener()
  • prependOnceListener()
  • setMaxListeners()

The following methods are compatible with new features:

The following method is partially compatible:

  • server.emit(criteria, data, [callback]) - the method only accept a single data argument for emitting events. In order to emit multiple argument, the event must be registered with the spread option and the data argument passed an array of the arguments applied to the listeners.

The following methods are unchanged:

  • removeListener(name, listener)
  • removeAllListeners(name)

And adds the following methods:

  • server.event(events) - the method must be called before server.emit() is called to emit application-specific events.


  • If you only use server.on(), server.once(), server.addListener(), or the other unmodified methods, your code should work as-is without changes.
  • Verify you do not use any of the methods no longer supported.
  • If you "abused" the emitters to emit your own application events, you will now need to properly register those events using the new server.event() method. You will also have to note the changes to server.emit() and if you need to pass more than one argument to the event listeners, to use the spread options and pass an array as data. If you relied on the return value of server.emit() it is no longer present.

Default cookie properties

This release changes the default cookie settings to use the HttpOnly, Secure, and SameSite=Strict properties by default to any cookie set via the state() method. Note that cookies set directly with reply().header() are not affected.

While discouraged, to retain the previous behavior (v14 and older), set the server defaults:

const options = {
    connections: {
        state: {
            isHttpOnly: false,
            isSecure: false,
            isSameSite: false

const server = new Server(options);


  • Review all your cookie settings, including those used by other plugins (e.g. yar, hapi-auth-cookie, etc.) and ensure the new defaults are compatible with your needs.
  • Where possible, use the new defaults for enhanced security.
  • Existing explicit values to the above three options are unaffected.

reply() interface

There are three changes to the reply() interface:

  • Calling reply() with a third argument when not used in the authenticate() authentication strategy method throws an exception.
  • Calling reply.continue() with an argument when not used in the authenticate() authentication strategy method throws an exception, except -
  • When calling reply.continue() with an argument in the 'onPostHandler' and 'onPreResponse' extension methods, the argument is no longer ignored and is used to override the existing response. However, unlike reply(), it does not terminate the request lifecycle, executing any other extension handlers left.


  • Review your code for any place where reply() is called with more than two arguments. reply is often passed as the callback argument to other methods, including server methods. If those callback signature include additional arguments, the call will throw an exception. Note that cached server methods include a third ttl argument which will cause it to throw an exception. To avoid errors, replace reply with (err, result) => reply(err, result) when passing reply directly as a callback function. This will ensure only the first two argument are passed.
  • Ensure reply.continue() is never used with an argument except for the authenticate() method. You can use the new response override feature but first must ensure existing code works as expected.

Request logging

The request.getLog() is disabled by default, prevent memory allocation when the request logs are not needed. The new route log configuration option enables the logging.

To retain the previous behavior (v14 and older), set the server defaults:

const options = {
    connections: {
        routes: {
            log: true

const server = new Server(options);


  • Search your code for getLog and if found, ensure the route or server is configured to enable it using the route log option.



  • Ensure calls to server.register() do not rely on the callback to be called on the same tick when the plugin register() method returns on the same tick.
  • Check if you specify route validation rules at both the server/connection level and the individual route level. If you do, note that the route level will completely override the global configuration per input source (e.g. overriding headers has no impact on params). If a route specifies its own validation rules, those rules must explicitly include the global rules as they will completely override them.
@hueniverse hueniverse added this to the 15.0.0 milestone Aug 26, 2016
@hueniverse hueniverse self-assigned this Aug 26, 2016
@hueniverse hueniverse closed this Aug 26, 2016
@lock lock bot locked as resolved and limited conversation to collaborators Jan 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant