-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Re-instate .lazy(..) to support Mutually Recursive Schemas? #2611
Comments
Lazy cannot be described and therefore is not going to be added back. Maybe @Marsup has ideas for you no how to implement what you need. |
If you can write it in a single pass, this could be an option. |
Thanks @Marsup . This works well for self-recursion, but it doesn't seem to work for the mutual recursion example above. To use schema.org as an example, you can implement the fact that Enumeration can take an Enumeration in its const Enumeration = Joi.object({
supersededBy: Joi.link('/'),
}) But schema.org also allows values of type const Enumeration = Joi.object({
supersededBy: Joi.alternatives().try(
Joi.link('/'), // Enumeration
Class, // This won't work as Class hasn't been defined yet
),
});
const Class = Joi.object({
supersededBy: Joi.alternatives().try(
Enumeration,
Joi.link('/'), // Class
),
}); For now, I have downgraded to Joi v14, where I'm doing this as follows: const Enumeration = Joi.object({
supersededBy: Joi.alternatives().try(
Joi.lazy(() => Enumeration),
Joi.lazy(() => Class),
),
});
const Class = Joi.object({
supersededBy: Joi.alternatives().try(
Joi.lazy(() => Enumeration),
Joi.lazy(() => Class),
),
}); |
I'm trying to validate the following structure: const linkSchema = Joi.object({
type: 'link',
target: Joi.string(),
});
const categorySchema = Joi.object({
type: 'category',
items: Joi.array().items(itemSchema),
});
const itemSchema = Joi.object().when('.type', {
switch: [
{is: 'link', then: linkSchema},
{is: 'category', then: categorySchema},
],
}); The problem is, both /ping @Marsup |
@hueniverse Do you have any idea if the pattern above is supported by Joi now? |
I think I was running into a similar issue when writing a validation generator for OpenApi 3(.1) definitions.
It seems to be a bit cumbersome if you want X and Y separated in different modules (I think), since the import interdependecy can only be resolved properly by putting each statement above in its own file (I can give details if anybody is interested or wants to invalidate this claim 😅). Alternatively, custom (sync) or external (async) could help for this use-case. I played around with the following draft which also seems to work and can probably be ported to external (async) usage with e.g. #2773. My use-case required to carry over artifacts in particular. I haven't yet looked into error handling.
and
and This can probably be put into a custom extension instead, which is also why I don't quite get the "Lazy cannot be described" argument in this respect. |
Support plan
Context
What problem are you trying to solve?
I would like to use JOI for the validation logic for a set of structural types which include some mutually recursive references.
A limited example just to demonstrate the point:
This obviously won't work as
Y
will be undefined in the first line. This also wouldn't be achievable using.link(..)
as.link(..)
(as far as I can tell) only works for referencing things within the one schema's boundaries itself. i.e. I initially tried:But, upon, trying to validate something, received the error
Error: "a" contains link reference "ref:local:Y" which is outside of schema boundaries
. This agrees with the docs here.In v15, there was a function
.lazy(..)
which supports this approach. It would allow:.lazy(..)
was deleted in v16 (release notes)To help give more context, I'm writing something that generates JOI validation schemas out of schema.org. schema.org models have many mutually recursive references e.g. https://schema.org/Enumeration references https://schema.org/Class (in
supersededBy
), which references https://schema.org/Enumeration again, etc etc.Do you have a new or modified API suggestion to solve the problem?
Re-introducing
.lazy(..)
as it was in v15 (https://joi.dev/api/?v=15.1.1#lazyfn-options---inherits-from-any).The text was updated successfully, but these errors were encountered: