'Joi - make everything required by default?
I'm building out a Node/Express API and using Joi for validation. It's a great package and has been incredibly useful. However, we're getting tired of doing things like:
const mySchema = joi.object({
thing1: joi.string().required(),
thing2: joi.string().required(),
thing3: joi.string().required(),
thing4: joi.string().required(),
thing5: joi.string().required(),
}).required();
We'd like everything to be required by default, and manually call .optional
to override that. In fact this seems a sensible default - but leaving that aside for now.
Is there a way to achieve this?
Solution 1:[1]
You can use presence
option to make fields required by default. Example:
const mySchema = joi.object({
thing1: joi.string(),
thing2: joi.string(),
thing3: joi.string(),
thing4: joi.string(),
thing5: joi.string(),
}).options({ presence: 'required' }).required();
Solution 2:[2]
There does not exist a standard way of making every key required, but there are workarounds.
One of the workaround can be usage of .requiredKeys()
and .optionalKeys()
on Joi.object()
Have a look at .describe()
function,
It returns an object which has a key flags
.
When a key is marked as 'optional', we get flags.presence = 'optional'
Using that information, you can call .describe()
on each key and prepare two arrays of requiredKey
and optionalKeys
And then, you can pass those arrays to .requiredKeys()
and .optionalKeys()
respectively.
For example:
Say you define your joi schema as:
const joiSchemaKeys = {
thing1: Joi.string(),
thing2: Joi.string().optional(),
thing3: Joi.string(),
thing4: Joi.string(),
thing5: Joi.string().required()
};
You can then prepare two arrays optionalKeys
and requiredKeys
using this:
const initialKeyInformation = {
requiredKeys: [],
optionalKeys: []
};
const prepareKeysInformation = keys =>
Object.keys(keys).reduce((accumulated, aKey) => {
const description = keys[aKey].describe();
const isMarkedOptional =
description.flags &&
description.flags.presence &&
description.flags.presence === "optional";
if (isMarkedOptional) {
console.log(`"${aKey}" is marked optional`);
accumulated.optionalKeys.push(aKey);
} else {
console.log(`"${aKey}" is not marked, making it required`);
accumulated.requiredKeys.push(aKey);
}
return accumulated;
}, initialKeyInformation);
const { optionalKeys, requiredKeys } = prepareKeysInformation(joiSchemaKeys);
Once that is done, you can prepare your joi schema like:
const schema = Joi.object()
.keys(joiSchemaKeys)
.requiredKeys(requiredKeys)
.optionalKeys(optionalKeys);
So this way, you will make every key required unless specified otherwise.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Anand Undavia |