Skip to content

Commit afe902a

Browse files
authored
Merge pull request #1486 from json-schema-org/gregsdennis/adr-object-contains
add adr for 'object contains'
2 parents 01c9163 + 192dcff commit afe902a

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed

Diff for: adr/2024-02-object-contains.md

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# `contains` and JSON Objects
2+
3+
* Status: Proposed, accepted, reconsidered, and ultimately reverted.
4+
* Deciders: @gregsdennis, @jdesrosiers, @handrews, @awwright, @karenetheridge, @relequestual (with input from a couple non-core members)
5+
* Date: 2023-11-14 (documented 2024-02-09)
6+
7+
Technical Story:
8+
9+
- Original proposal [#1077](https://github.com/json-schema-org/json-schema-spec/issues/1077) and [PR](https://github.com/json-schema-org/json-schema-spec/pull/1092)
10+
- Reversion discussion [#1358](https://github.com/json-schema-org/json-schema-spec/issues/1358) and [PR](https://github.com/json-schema-org/json-schema-spec/pull/1452)
11+
12+
## Context and Problem Statement
13+
14+
[2021-02]
15+
The original proposal was for `contains` to apply to objects as well as arrays since there was no functionality to do so.
16+
The discussion covered the options of modifying `contains` or introducing a new `objectContains` (or similar) keyword set (also needs separate min/max).
17+
The decision was voted on and modifying `contains` won.
18+
19+
[2021-06]
20+
A change was applied.
21+
22+
[2022-12]
23+
With the team shifting focus to stability between spec releases, the question was raised again with the argument that allowing `contains` to apply to objects is a breaking change.
24+
It was conceded that the better approach would be to retain `contains` only for arrays and introduce a new keyword set to apply to objects.
25+
26+
[2023-11]
27+
The change was applied (reverted to previous behavior).
28+
29+
## Decision Drivers <!-- optional -->
30+
31+
* The original decision to allow `contains` to apply to objects was driven by the fact that no such functionality existed.
32+
* The decision to revert was driven by a desire to not break current usages of `contains`.
33+
34+
## Considered Options
35+
36+
* `contains` could be modified to apply to objects.
37+
* a new keyword set (e.g. `objectContains` along with associated min/max) could be added.
38+
39+
## Decision Outcome
40+
41+
Ultimately, `contains` will continue to apply to only arrays.
42+
New keywords will need to be introduced to apply to objects.
43+
(Such a proposal has not yet been made.)
44+
45+
### Positive Consequences <!-- optional -->
46+
47+
* Schemas which currently use `contains` without a `type: array` specifier will not suddenly start applying to objects also.
48+
49+
### Negative Consequences <!-- optional -->
50+
51+
* The functionality of `contains` as applied to objects is still unsupported.
52+
53+
## Pros and Cons of the Options <!-- optional -->
54+
55+
### Change `contains`
56+
57+
(Example provided recently by a user in [Slack](https://json-schema.slack.com/archives/C5CF75URH/p1707258032879409))
58+
59+
The requirement is that an object may contain any number of properties, but one and only one of them must contain an object with a `title` property.
60+
61+
✔️ valid
62+
```json
63+
{
64+
"foo": { "title": "a title" },
65+
"bar": { "baz": 42 }
66+
}
67+
```
68+
69+
❌ invalid
70+
```json
71+
{
72+
"foo": { "quux": false },
73+
"bar": { "baz": 42 }
74+
}
75+
```
76+
77+
❌ invalid
78+
```json
79+
{
80+
"foo": { "title": "a title" },
81+
"bar": { "title": "a title" }
82+
}
83+
```
84+
85+
Currently, this is impossible since there is no way to conditionally count property values.
86+
However, with `contains` applying to objects, the following is possible:
87+
88+
```json
89+
{
90+
"type": "object",
91+
"contains": {
92+
"type": "object",
93+
"required": ["title"]
94+
},
95+
"minContains": 1,
96+
"maxContains": 1
97+
}
98+
```
99+
100+
* Good, because it provides functionality that previously did not exist
101+
* Bad, because is can potentially break some schemas
102+
*<!-- numbers of pros and cons can vary -->
103+
104+
### New keywords
105+
106+
Same examples as [changing `contains`](#change-contains), except we use new keywords instead.
107+
108+
The schema would be something like this instead:
109+
110+
```json
111+
{
112+
"type": "object",
113+
"objectContains": {
114+
"type": "object",
115+
"required": ["title"]
116+
},
117+
"objectMinContains": 1,
118+
"objectMaxContains": 1
119+
}
120+
```
121+
122+
* Good, because it provides functionality that previously did not exist
123+
* Good, because it doesn't break anyone
124+
* Bad, because we have to introduce three new keywords
125+
*<!-- numbers of pros and cons can vary -->

0 commit comments

Comments
 (0)