I have this piece of code
const baseSchema = Joi.object.keys({
name: Joi.string().required()
})
Now I want to add more keys to this schema, I can write
const basicInfoSchema = baseSchema.keys({
address: Joi.string().required(),
phoneNumber: Joi.number().required()
})
or
const basicInfoSchema = baseSchema.append({
address: Joi.string().required(),
phoneNumber: Joi.number().required()
})
What's the difference between the two?
append
has a generic parameter to give some typing to the expected object. Like Joi.object<>()
does. keys
has no generic parameter.
Also looking at the source code bellow (version 17.6.0), you can see append calls keys
under the hood. I won't paste the documentation, but you can read it there https://joi.dev/api/?v=17.6.0 .
Basically, append
only do the else
clause of keys
method. While keys
can also "Allow all" (any key allowed) or "Allow none" (no keys allowed) of the existing keys. keys
has two extra functionalities.
append: {
method(schema) {
if (schema === null ||
schema === undefined ||
Object.keys(schema).length === 0) {
return this;
}
return this.keys(schema);
}
},
keys: {
method(schema) {
Assert(schema === undefined || typeof schema === 'object', 'Object schema must be a valid object');
Assert(!Common.isSchema(schema), 'Object schema cannot be a joi schema');
const obj = this.clone();
if (!schema) { // Allow all
obj.$_terms.keys = null;
}
else if (!Object.keys(schema).length) { // Allow none
obj.$_terms.keys = new internals.Keys();
}
else {
obj.$_terms.keys = obj.$_terms.keys ? obj.$_terms.keys.filter((child) => !schema.hasOwnProperty(child.key)) : new internals.Keys();
for (const key in schema) {
Common.tryWithPath(() => obj.$_terms.keys.push({ key, schema: this.$_compile(schema[key]) }), key);
}
}
return obj.$_mutateRebuild();
}
},