-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
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
- Only support node v12 or newer. Will not work at all on node v11 or older (Drop support for node v8 #3910, Drop node 10 #4012, Use private class fields #4013).
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).- No joi schema compiler is loaded by default and must be explicitly loaded using
server.validator(require('@hapi/joi'))if uncompiled schemas are using in configuration (server.validator() #4006). - Remove support for request queueing (
server.load.concurrent) (Remove request queue (options.load.concurrent) #3977). - Change the route
options.payload.multiparttofalseby default (Change routes.payload.multipart to false by default #3920). - Change default empty status code to
204from200(Change emptyStatusCode to 204 by default #3919). request.info.remoteAddressandrequest.info.remotePortare only populated upon access.
New Features
- Support multiple joi schema compilers at the same time allowing each plugin to specify the version of joi it is using (server.validator() #4006).
- Support
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). - Always include auth artifacts regardless of auth status (auth scheme artifacts are dropped when mode is not 'try' #4000).
Bug fixes
- Support request decorations using symbols and runtime apply (Decorate requests with symbols with apply=true #3996).
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.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 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 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:
{
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
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:
- Look for
server.load.concurrentconfiguration 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
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.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.remoteAddressandrequest.info.remotePortproperties when requests are aborted, use the routeinfo.remotesettings set totrue.