I have a route with an optional payload. After upgrading to v9, the route returns 400 when the payload is missing. I assume this is because an empty payload is now transformed to null instead of {}, and when null is passed to Joi, Joi responds with "value" must be an object.
To reproduce:
var Hapi = require('hapi');
var Joi = require('joi');
// Create a server with a host and port
var server = new Hapi.Server();
server.connection({
host: 'localhost',
port: 8000
});
// Add the route
server.route({
method: 'POST',
path: '/hello',
config: {
validate: {
payload: {
name: Joi.string()
}
},
handler: function (request, reply) {
reply('hello ' + (request.payload.name || 'world'));
}
},
});
// Start the server
server.start(function() {
console.log('Server running at:', server.info.uri);
});
My use case is an action for resetting a password, where users are allowed to provide a password in the payload, but if a password is not provided, we generate one automatically.
This definitely looks like a bug. Essentially, the value null is suppied to Joi.validate() when a POST request is empty and contains no content-type header.
The same happens if content-type is set to text/plain or application/json, or if it's not set at all.
It is possible that this is not a bug, but simply a consequence of the updated payload parsing. At least I managed to find a work around:
server.route({
method: 'POST',
path: '/hello',
config: {
validate: {
payload: Joi.object({
name: Joi.string()
}).allow(null)
},
handler: function (request, reply) {
reply('hello ' + ((request.payload || {}).name || 'world'));
}
}
});
allow(null) works for me. I had to change how I check for empty payload, but that's ok.
@hueniverse perhaps this can be resolved by noting in the "Empty Payload" section of the 9.0.0 migration checklist (#2682) how to field empty request payloads (that are allowed to be empty) when using Joi validation. The pattern is to use Joi.object(/* ... */).allow(null).
Related to #2576 ?
Most helpful comment
It is possible that this is not a bug, but simply a consequence of the updated payload parsing. At least I managed to find a work around: