Friday, May 17, 2024
 Popular · Latest · Hot · Upcoming
140
rated 0 times [  143] [ 3]  / answers: 1 / hits: 17023  / 10 Years ago, mon, october 6, 2014, 12:00:00

My goal is to create a index route for posts. User should be able to specify some query params (ie. tags, type) but shouldn't be able to specify others. To clarify:



This is okay:



/posts
/posts?tags=food
/posts?type=regular&tags=stackoverflow


This is not okay:



/posts?title=Hello


This is hapi pack config:



servers: [
{
host: 'localhost',
port: 3000,
options: {
labels: [api],
validation: {
abortEarly: false,
presence: 'forbidden'
}
}
}
],


Please notice the presence: forbidden option.



This is route config:



handler: function (request, reply) {
Post.find(request.query, function (err, posts) {
if(err) {
console.log(err);
}

reply(posts);
});
},
validate: {
query: {
type: Joi.string().optional(),
tags: Joi.string().optional()
}

}


My idea was that the validation should allow any subset of type and tags params (including empty query). However, after making any of allowed requests i'm getting a following error:



{
statusCode: 400,
error: Bad Request,
message: value is not allowed,
validation: {
source: query,
keys: [
value
]
}
}


Why is that? There is of course no key named value. How to make the validation behave the way i want it to?


More From » node.js

 Answers
26

If you define a non-type schema object, Joi converts it internally to an object() type. So this schema:



var schema = {
type: Joi.string().optional(),
tags: Joi.string().optional()
};


becomes:



var schema = Joi.object().keys({
type: Joi.string().optional(),
tags: Joi.string().optional()
});


Because you set presence to forbidden in server settings, it is applied to the object type, so the schema becomes:



var schema = Joi.object().forbidden().keys({
type: Joi.string().optional(),
tags: Joi.string().optional()
});


As you can see it marks the main object as forbidden which will not allow any value except undefined:



var Joi = require('joi');

var schema = Joi.object().forbidden().keys({
type: Joi.string().optional(),
tags: Joi.string().optional()
});

var value = {};

Joi.validate(value, schema, { presence: 'forbidden' }, function (err, value) {

console.log(err);
});


It outputs:



{ [ValidationError: value is not allowed]
name: 'ValidationError',
details:
[ { message: 'value is not allowed',
path: 'value',
type: 'any.unknown' } ],
_object: {},
annotate: [Function] }


So what you need to do is to mark the main object either required or optional to override forbidden:



validate: {
query: Joi.object().required().keys({
type: Joi.string().optional(),
tags: Joi.string().optional()
})
}

[#69226] Friday, October 3, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
karladaijahf

Total Points: 78
Total Questions: 123
Total Answers: 89

Location: Liechtenstein
Member since Wed, Dec 8, 2021
2 Years ago
;