We would like share some Joi schema between two separate apps.
We found in the basecode the 'describe()' and 'compile()' method that seems to offer this fonctionnality.
Our naive approach failed.
var Joi = require('joi');
var schema = Joi.object({
name: Joi.string().default("Joe"),
});
var internalSchemaDef = schema.describe();
var compile = Joi.compile(internalSchemaDef);
with the following error (joi 3.1.0)
/tmp/node_modules/joi/node_modules/hoek/lib/index.js:349
throw new Error(msgs.join(' ') || 'Unknown error');
^
Error: Invalid schema content:
Are we in a good way ? or perhaps we missunderstood the 'describe' and 'compile' usage.
That is not the purpose of describe or compile. describe() is used to provide an easy to walk and consume tree of information about a Joi schema for purposes such as code annotation and documentation. compile() as I understand it, is used to take a literal object and convert it into a simple Joi schema as an alternate method of initially defining the schema without Joi.
Ok thanks for your input.
Another question,
Are there another method or technical for
generate a description's schema usable in compile()
exemple :
var schema = Joi.alternatives().try([
Joi.string().valid('key'),
Joi.number().valid(5),
Joi.object().keys({
a: Joi.boolean().valid(true),
b: Joi.alternatives().try([
Joi.string().regex(/^a/),
Joi.string().valid('boom')
])
})
]);
var definition = schema.def()
console.log(definition);
//=>['key', 5, { a: true, b: [/^a/, 'boom'] }];
perhaps existe somethings for do like that ?
As far as I understand it, the literal syntax which compile() accepts is strictly a subset of what a full Joi schema can validate. Thus, any conversion from a full schema to the literal syntax would necessarily be lossy. I can't really think of a good way that would be implemented without biting anyone that doesn't have a solid understanding of its limitations.
What is the use case? At my company, we share Joi schemas between many systems. We do this by having a module containing our schemas (used for validating our database interactions) and then require that module in other systems that require it (such as our API server). Our API sever can then access the Joi schemas exported by the shared module.
If you're instead looking to serialize them over the wire, I think it would be more promising to try serializing/reconstituting them directly from their schema forms. e.g.
var schema = Joi.alternatives().try([Joi.string(), Joi.number().integer()]);
var message = JSON.stringify(schema);
// ... send the message
// receive the message
var message = payload.message
var rawSchema = JSON.parse(message);
// magic
var schema = Joi[rawSchema._type]().concat(rawSchema);
The final line is used to create a new Joi schema with the proper prototype chain that also contains all of the appropriate information from the old schema. It would be nice if we could just do something like Joi.any().clone.call(rawSchema), but it chooses it's prototype based on this's prototype, so that doesn't work. It would be cool to have a proper public function to get the base type of a joi schema though, since it's not nice to rely on private properties.
There is no current way to take the output of describe() and convert it back into a schema. I am sure someone can write one. The above is good advice on sharing rules.
I was about to ask whether there's an uncompile() method to serialize a joi schema to JSON to transfer it to the client, but apparently that's a no :(
Is there any chance of getting this added as a public method? We'd like to serialize/deserialize schemas.
I looked into doing this before, and it's definitely pretty difficult right now. It could probably eventually be done with #577 but there would need to be a lot more updates that occur before that could happen. I'd just suggest using a shared module, so much easier right now.
Is there any update on this? How can I convert describe() back to schema?
There is no current functionality to do that, no. And I am unaware of any effort to add it.
@joshuafcole your solution doesn't work for me :( I'm getting a Converting circular structure to JSON during the JSON.stringify, even if I remove the circular structure after that the concat give me Invalid schema object :(
Same error above yet. And unfortunately it seems to exist no way back from .describe() to recreate a joi instance. This is a problem because I am saving my joi instance in a database and using it programmatically. I can store it but I can't recreate it to use as a valid joi? That's frustrating...
This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.
Most helpful comment
Ok thanks for your input.
Another question,
Are there another method or technical for
generate a description's schema usable in
compile()exemple :
perhaps existe somethings for do like that ?