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

Allow contains to apply to objects as well as arrays #1092

Merged
merged 5 commits into from
Jun 4, 2021

Conversation

jdesrosiers
Copy link
Member

Resolves #1077

The two ways to go with this were to have contains/minContains/maxContains apply to objects, or to introduce three new keywords that apply to objects. I went with the first option because that was the only one anyone expressed a preference for and no one objected.

<xref target="json-schema">"contains"</xref> keyword. The first way is if
the annotation result is an array and the length of that array is less than
or equal to the "maxContains" value. The second way is if the annotation
result is a boolean "true" and the instance array length is less than or
equal to the "maxContains" value.
result is a boolean "true" and the instance length is less than or equal to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can "length" be applied to objects? Maybe we keep "instance array length" and add "or property count"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "length" makes sense. It may be an object, but in this context, it's being treated like a map, which does have a concept of length. But I you think it's questionable, others will be confused, so we should be more explicit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"number of properties" is explicit and doesn't depend on a language/framework's particular data model.

<xref target="json-schema">"contains"</xref> keyword. The first way is if
the annotation result is an array and the length of that array is greater
than or equal to the "minContains" value. The second way is if the
annotation result is a boolean "true" and the instance array length is
greater than or equal to the "minContains" value.
annotation result is a boolean "true" and the instance length is greater
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

@karenetheridge
Copy link
Member

I think this keyword should be moved out of this section entirely -- as it is presently located in "Keywords for Applying Subschemas to Arrays". It can be moved to a third section after "Keywords for Applying Subschemas to Objects", called "Keywords for Applying Subschemas to Arrays or Objects", or even just "Other Keywords for Applying Subschemas".

@awwright
Copy link
Member

What happens if someone wants to specify that an array to contain an item, OR that an object to contain a property value?

I would like to suggest these should be different keywords, e.g. containsItem or containsValue/containsProperty

@gregsdennis
Copy link
Member

What happens if someone wants to specify that an array to contain an item, OR that an object to contain a property value? - @awwright

If they only wanted one or the other, they would need to also specify type, which is the current solution to that need anyway.

@jdesrosiers
Copy link
Member Author

@awwright If you think this needs more discussion, please comment on #1077. I'm happy to put this PR on hold until consensus is achieved, but that discussion should take place on the issue, not here.

@awwright awwright mentioned this pull request Apr 21, 2021
Copy link
Member

@Relequestual Relequestual left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable to me.
Want to see all PRs adding to the changelog to avoid the mess of making a changelog at the end 😅

  • Added to changelog

@jdesrosiers
Copy link
Member Author

Good thinking about adding to the change log! It sounds like this PR might get closed as preference seems to be shifting toward using new keywords. When it's decided, I will make sure whichever one we go with is included in the changelog.

@handrews
Copy link
Contributor

While it sounds like this PR is a bit in-limbo, if that changes and it's re-approved, it would be good to wait to merge until we decide whether to branch for the next major draft.

@handrews handrews marked this pull request as draft May 12, 2021 16:21
@jdesrosiers
Copy link
Member Author

It appears we have general consensus on this direction, so I'm removing "draft" status to open this up for review. However, @handrews, I will not merge until we decide what's happening with the bug-fix draft. This should not be included in the bug-fix draft.

@jdesrosiers jdesrosiers marked this pull request as ready for review May 14, 2021 18:31
@jdesrosiers
Copy link
Member Author

I had the create a new section for the change log because it doesn't exist yet. I used draft-bhutton-json-schema-next as the draft identifier because it's not certain which draft we will be on when this gets released if there are one or more bug-fix drafts. It will have to be updated when the next full draft release is near.

@handrews handrews changed the base branch from master to draft-next May 19, 2021 19:06
@handrews handrews added this to the draft-next milestone May 19, 2021
Copy link
Contributor

@handrews handrews left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work on reaching this solution!

@jdesrosiers jdesrosiers merged commit 1cec0c2 into json-schema-org:draft-next Jun 4, 2021
@jdesrosiers jdesrosiers deleted the object-contains branch June 4, 2021 17:59
@jdesrosiers
Copy link
Member Author

I just want to include a quick summary of the discussion around adding this keyword.

There was no opposition to adding contains-like functionality that applies to objects. This functionality was already possible in JSON Schema using the following pattern.

{
  "not": {
    "patternProperties": {
      "": { "not": { ... schema ... } }
    }
  }
}

Note: I used patternProperties instead of additionalProperties to make it explicit that it should not be affected by defined properties.

The only point of contention was whether contains should apply to objects as well as arrays, or there should be new keywords that only apply to objects. Using the same keyword could result in backwards incompatible behavior in very rare (and poorly designed) situations. But it can also be useful such as describing a value that can be an object or an array, but either way, it must contain some value. However, the main benefit of using the same keywords is that it's easy for schema authors to understand and allows us to avoid adding three new keywords.

In the end, the only people expressing strong preferences were for overloading contains and there was only one person with a slight preference for new keywords. So, went with overloading contains.

@karenetheridge
Copy link
Member

I noticed there were no changes to meta/applicator.json. Shall we do those in a subsequent PR?

@jdesrosiers
Copy link
Member Author

I don't think there are any meta-schema changes needed for this. Am I missing something?

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

Successfully merging this pull request may close these issues.

Object-based contains
6 participants