Summary
hapi v19.0.0 is a small size release with a few changes to improve performance, support for multiple versions of joi schemas, and standards compliance.
- Upgrade time: low - none to a couple of hours for most users
- Complexity: low - requires following the list of changes to verifying their impact
- Risk: low - small number of changes with simple ways to retain previous behavior in most cases
- Dependencies: medium - most existing plugins will work as-is, however plugins with scoped names might require changes to retain scope in exposed plugin APIs
Breaking Changes
New Features
Bug fixes
Migration Checklist
Node version
Make sure your node version is v12.14.1 or newer. This release uses language features that are only available in node v12 or higher and will not even start on older versions. Node v12 is the current LTS and the recommended version of node.
Request payload override
The request.payload property is now initialized to undefined instead of null when accessed in an onResponse extension handler. If modified, it will cause payload processing to bypass instead of just being overridden later by the framework.
Checklist:
- Look for
request.payload access in onRequest handlers and make sure you are not expecting null specifically. If the value is being modified, note that it will now "stick".
Exposed plugin APIs
When using server.expose() in a plugin with a scoped name (e.g. @hapi/example), the object key set under server.plugins will no longer include the scope (e.g. @hapi/), unless the new scope option is set. This may only impact your code if you are using scoped plugins.
Checklist:
- Look for references to
server.plugins['@ which will need to be updated to exclude the plugin scope or upgrade your plugin module to a newer version designed to work with hapi v19 and explicitly set the handling of scope prefixes.
- If you are a plugin author (public or private) and would like to keep the scopes in the exposed API path, add the new
{ scope: true } option as the third argument to server.expose().
joi Schema Compiler
In previous versions, hapi included a built-in joi schema compiler that allowed setting validation rules without a top level joi wrapper:
{
validate: {
payload: {
name: Joi.string().required()
}
}
}
instead of the explicit version which is more verbose and less readable:
{
validate: {
payload: Joi.object({
name: Joi.string().required()
})
}
}
The inclusion of a default schema compiler caused problems every time the version of the compiler changed and forced developers to update their schemas.
This release removes the default compiler and adds a new server.validator() method which takes a direct reference to the joi module used. It only sets the compiler for the current realm and its sub-realms, allowing each plugin to specify it's own validation compiler and not worry about mixing versions.
Checklist:
- Check your code for route
validate and response.schema settings and if you are passing values that must be compiled (see above for the lack of Joi.object() as a typical case), either wrap your schema with Joi.object() or call server.validator(Joi).
Remove support for request queueing
This rarely used feature was removed without a replacement.
Checklist:
- Look for
server.load.concurrent configuration and remove it.
Change route options.payload.multipart to false by default
Route configuration default was change to disable multipart processing. You will need to either enable it for the entire server to keep previous behavior or just for the routes where multipart processing is required.
Change default empty status code to 204
The HTTP standard defines a 204 status code for responses with an empty payload. In previous versions of the framework, empty responses used the 200 status code unless the emptyStatusCode configuration option was explicitly set to 204. The new default is 204 which can be explicitly set to 200.
This change mostly affect tests and some strict API clients that check the status code to be exactly 200 vs any 2xx response. If you are not sure about it or rather not deal with it, simply set emptyStatusCode back to 200.
Checklist:
- Look for existing
emptyStatusCode configuration. If it is set to 204 you can remove it (or leave it). If there is no configuration and you would like to keep previous behavior add a server level config with emptyStatusCode set to 200.
request.info.remoteAddress and request.info.remotePort
The properties have been changed to use getters and are only populated when requested. This is a performance optimization as those are slow calls that should only be performed when actually needed. The breaking change is due to the fact that these values are no longer available if the request is aborted.
Checklist:
- If you rely on the -
request.info.remoteAddress and request.info.remotePort properties when requests are aborted, use the route info.remote settings set to true.
Summary
hapi v19.0.0 is a small size release with a few changes to improve performance, support for multiple versions of joi schemas, and standards compliance.
Breaking Changes
request.payloadis initialized toundefinedinonResponseand if modified, will cause payload processing to bypass (Do not override request.payload if set manually in onRequest #4015).server.expose()when used in a plugin with a scoped name (e.g.@hapi/example) will no longer include the scope (e.g.@hapi/) prefix inserver.plugins, unless the newscopeoption is set (Change scoped plugins name handling #4011).server.validator(require('@hapi/joi'))if uncompiled schemas are using in configuration (server.validator() #4006).server.load.concurrent) (Remove request queue (options.load.concurrent) #3977).options.payload.multiparttofalseby default (Change routes.payload.multipart to false by default #3920).204from200(Change emptyStatusCode to 204 by default #3919).request.info.remoteAddressandrequest.info.remotePortare only populated upon access.New Features
SameSite=Noneand the ability to customize cookie settings per-request in runtime which is required for some Chrome 80 migrations (Support SameSite=None for cookies #3987).Bug fixes
Migration Checklist
Node version
Make sure your node version is v12.14.1 or newer. This release uses language features that are only available in node v12 or higher and will not even start on older versions. Node v12 is the current LTS and the recommended version of node.
Request payload override
The
request.payloadproperty is now initialized toundefinedinstead ofnullwhen accessed in anonResponseextension handler. If modified, it will cause payload processing to bypass instead of just being overridden later by the framework.Checklist:
request.payloadaccess inonRequesthandlers and make sure you are not expectingnullspecifically. If the value is being modified, note that it will now "stick".Exposed plugin APIs
When using
server.expose()in a plugin with a scoped name (e.g.@hapi/example), the object key set underserver.pluginswill no longer include the scope (e.g.@hapi/), unless the newscopeoption is set. This may only impact your code if you are using scoped plugins.Checklist:
server.plugins['@which will need to be updated to exclude the plugin scope or upgrade your plugin module to a newer version designed to work with hapi v19 and explicitly set the handling of scope prefixes.{ scope: true }option as the third argument toserver.expose().joi Schema Compiler
In previous versions, hapi included a built-in joi schema compiler that allowed setting validation rules without a top level joi wrapper:
instead of the explicit version which is more verbose and less readable:
The inclusion of a default schema compiler caused problems every time the version of the compiler changed and forced developers to update their schemas.
This release removes the default compiler and adds a new
server.validator()method which takes a direct reference to the joi module used. It only sets the compiler for the current realm and its sub-realms, allowing each plugin to specify it's own validation compiler and not worry about mixing versions.Checklist:
validateandresponse.schemasettings and if you are passing values that must be compiled (see above for the lack ofJoi.object()as a typical case), either wrap your schema withJoi.object()or callserver.validator(Joi).Remove support for request queueing
This rarely used feature was removed without a replacement.
Checklist:
server.load.concurrentconfiguration and remove it.Change route
options.payload.multiparttofalseby defaultRoute configuration default was change to disable multipart processing. You will need to either enable it for the entire server to keep previous behavior or just for the routes where multipart processing is required.
Change default empty status code to
204The HTTP standard defines a 204 status code for responses with an empty payload. In previous versions of the framework, empty responses used the
200status code unless theemptyStatusCodeconfiguration option was explicitly set to204. The new default is204which can be explicitly set to200.This change mostly affect tests and some strict API clients that check the status code to be exactly
200vs any2xxresponse. If you are not sure about it or rather not deal with it, simply setemptyStatusCodeback to200.Checklist:
emptyStatusCodeconfiguration. If it is set to204you can remove it (or leave it). If there is no configuration and you would like to keep previous behavior add a server level config withemptyStatusCodeset to200.request.info.remoteAddressandrequest.info.remotePortThe properties have been changed to use getters and are only populated when requested. This is a performance optimization as those are slow calls that should only be performed when actually needed. The breaking change is due to the fact that these values are no longer available if the request is aborted.
Checklist:
request.info.remoteAddressandrequest.info.remotePortproperties when requests are aborted, use the routeinfo.remotesettings set totrue.