I need to create dynamic schema to validate my api request query in node js
using Joi validator depending on a key in the request query. Say the following below mentioned pattern are my valid queries.
I'm using hapi/joi
version 16.1.8
Combination 1
{ type: 1, firstname: 'user first name', lastname: 'user last name'}
Combination 2
{ type: 2 , salary: 1000, pension: 200}
Combination 3
{ type: 3 , credit: 550, debit: 100}
As you can see the object keys varies depending on the value of type
. How this can be handled properly?
We can handle two conditions using Joi.alternatives like
const schema = Joi.alternatives().conditional(Joi.object({ type: 1 }).unknown(), {
then: Joi.object({
type: Joi.string(),
firstname: Joi.string(),
lastname: Joi.string()
}),
otherwise: Joi.object({
type: Joi.number(),
salary: Joi.any(),
pension: Joi.any()
})
});
But how this can be done for 3 conditions?
I achieved the same in a little different manner. Posting the same here since this might be useful for someone in future.
const schema = Joi.object({
type: Joi.number().required().valid(1, 2, 3),
firstname: Joi.alternatives().conditional('type', { is: 1, then: Joi.string().required() }),
lastname: Joi.alternatives().conditional('type', { is: 1, then: Joi.string().required() }),
salary: Joi.alternatives().conditional('type', { is: 2, then: Joi.number().required() }),
pension: Joi.alternatives().conditional('type', { is: 2, then: Joi.number().required() }),
credit: Joi.alternatives().conditional('type', { is: 3, then: Joi.number().required() }),
debit: Joi.alternatives().conditional('type', { is: 3, then: Joi.number().required() }),
}))
This was working perfectly as expected.
When the type value is 1
the object should have only type
, firstname
and lastname
When the type value is 2
the object should have only type
, salary
and pension
When the type value is 3
the object should have only type
, credit
and debit
Any other combination will be thrown as error from the joi validator middleware layer. Also any other type value other that 1, 2 and 3 will be throwing error.