Hi, how can I serialize a Joi schema? If I convert back/forth from JSON Schema, I feel like there are cases where information may be lost in complex schemas. JSON.stringify(schema) doesn't work either. Seems like there should be some way to do this, but I can't find anything.
.describe() is your best bet.
How do I deserialize a describe() output?
There is no way to go Joi schema -> serialized description -> re-constituted Joi schema that I am aware of.
I can confirm all that. It's not really joi's job to do serialization, an external module can perfectly accomplish that task if someone cares enough to put in the work.
If someones is looking for a solution, I wrote a module for this: joi-serialization.
It covers any of joi's functionality, except references and extensions. Be aware that in some cases the serialized object cannot be stringified loslessly, since it can contain references like e.g. a Symbol. For symbols there is an option to pass your own Symbol map on deserialization.
@lal12 this is now built-in in v16
@lal12 this is now built-in in v16
I wasn't aware of that, thanks.
Which api? I didn't found it in the docs.
describe() and build(). They are not documented yet but lots of examples in the tests.
describe()andbuild(). They are not documented yet but lots of examples in the tests.
This is huge. I currently have a use case where I'm ingesting a variety of survey results from different websites. Each one has different inclusion/exclusion criteria.
With this, I can now store all of my inclusion/exclusion rules as serialized Joi models in my database. That way, I can have a single applicant sorting lambda retrieve the appropriate validation rules and evaluate all entries.
example
const maxAge = 80;
var earliestDate = new Date();
earliestDate.setFullYear(earliestDate.getFullYear() - maxAge );
// create a valid date example
var validDate = new Date();
validDate.setFullYear(validDate.getFullYear() - (maxAge -1) );
// create our Joi model
const ExampleModel = Joi.object().keys({
firstName: Joi.string().optional(),
lastName: Joi.string().optional(),
DOB: Joi.date().iso().greater(earliestDate).optional(),
});
// create the model description object
const modelDescription = ExampleModel.describe();
// demonstrate that we can stringify this object and possibly store it in a DB
const stringified = JSON.stringify(modelDescription);
console.log('the stringified model is :', stringified);
// parse the model schema description into an object again
const reObjectified = JSON.parse(data);
// take the schema description object and create a Joi model from it
const RebuiltModel = Joi.build(reObjectified);
const invalidParticipant = {
firstName: "John",
lastName: "Smith",
DOB: earliestDate, // applicant is too old
};
const validParticipant = {
firstName: "Jack",
lastName: "Doe",
DOB: validDate,
};
const invalidValidationResult = RebuiltModel.validate(invalidParticipant);
if (invalidValidationResult.error) {
console.log(`${invalidParticipant.firstName} should NOT be allowed to proceed because :`, invalidValidationResult.error);
} else {
console.log('An invalid participant was let through!!!!!');
}
const validValidationResult = RebuiltModel.validate(validParticipant);
if (validValidationResult.error) {
console.log(`${validParticipant.firstName} was rejected!?!?!!?!`);
} else {
console.log(`${validParticipant.firstName} should be allowed to proceed`);
}
You could even store your Joi schema and have your frontend access it to do FE validation. Forget writing your form validation in two places. Just store it and make it available to FE and BE.
Most helpful comment
This is huge. I currently have a use case where I'm ingesting a variety of survey results from different websites. Each one has different inclusion/exclusion criteria.
With this, I can now store all of my inclusion/exclusion rules as serialized Joi models in my database. That way, I can have a single applicant sorting lambda retrieve the appropriate validation rules and evaluate all entries.
example
You could even store your Joi schema and have your frontend access it to do FE validation. Forget writing your form validation in two places. Just store it and make it available to FE and BE.