Skip to content
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

Reconsider allowing "contains" to apply to objects #1358

Closed
handrews opened this issue Dec 6, 2022 · 6 comments · Fixed by #1452
Closed

Reconsider allowing "contains" to apply to objects #1358

handrews opened this issue Dec 6, 2022 · 6 comments · Fixed by #1452

Comments

@handrews
Copy link
Contributor

handrews commented Dec 6, 2022

During yesterday's meeting, I brought up that in the time since we decided to allow "contains" to apply to objects, we've shifted to more of an emphasis on stability.

"contains" was added in draft-06, and while the details of its interactions with "minContains" and "maxContains" (added in 2019-09) have changed, its assertion behavior on its own has not. Allowing these three keywords to apply to objects is a breaking change.

We could instead revert them to apply only to arrays and introduce keywords named something like "containsPropertyValue", "minContainsPropertyValue", "maxContainsPropertyValue" alongside them. I'll let others sort out the ideal names. "containsProperty" might be fine but also feels a bit like it is talking about property names rather than values. Another option could be "hasValue" or "hasPropertyValue" or something of that sort. All of the name options are less aesthetically appealing than having "contains" work on objects, but they'd preserve more stability.

I don't have an incredibly strong opinion on this, but it seemed to get some traction in the call so I thought I'd file it.

@handrews handrews added this to the draft-next milestone Dec 6, 2022
@gregsdennis
Copy link
Member

We should follow the example we set with dependencies and just create two new keywords. I think containsItems and containsProperties would work nicely.

@handrews
Copy link
Contributor Author

handrews commented Dec 7, 2022

Creating containsItems would be a much bigger breaking change than keeping what we have on main right now. We've never published a contains that applies to objects, so there's nothing to split here. There's an existing keyword that only applies to arrays, and there's some unpublished text about objects.

@gregsdennis
Copy link
Member

Just thinking of maintaining symmetry.

@awwright
Copy link
Member

awwright commented Dec 8, 2022

Yes let's take a close look at this, as far as I can tell, this can definitely break some schemas, and makes some types of schemas more difficult to write. And what's worse, it's very difficult to look at a schema (this keyword by itself, at least) and determine which behavior the author intended.

It's also quite unusual for keywords to apply to more than one type of value (but not all of them). In this case, it now can invalidate/reject object or array instances, but not other types...? This impacts schemas such as:

{
type: ["array", "object"],
contains: { const: true },
properties: { "name": { type: "string" } }
}

It seems this change would break many instances of the form { "name": "" }, with newer validators rejecting the instance, but older ones accepting it (even ones that think they completely understand the "contains" keyword).

@jdesrosiers
Copy link
Member

I'm ok with changing it to be two keywords. If we do that, I agree that the array version should remain contains.

@gregsdennis
Copy link
Member

gregsdennis commented Jan 17, 2023

My perfectionism is twitching that these keywords will be asymmetric: contains and containsProperties.

Pendantically, containProperties isn't quite right, either, because we're not looking at properties, per se; we're looking at the values of those properties.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging a pull request may close this issue.

4 participants