Skip to content

Commit ea58536

Browse files
committed
Example of $recursiveRoot and $recursiveRef
THIS WILL NOT BE MERGED. This PR is being used to illustrate a proposal for issue json-schema-org#558. If the root schema of the entry point schema (the schema document at which schema evaluation begins) contains `"$recursiveRoot": true` then that entry point is set throughout the schema evaluation process as the target of all `"$recursiveRef"` references, regardless of their values. Encountering additional `"$recursiveRoot"` keywords in non-entry point schema documents has _no effect_. The keyword MUST be ignored in subschemas, and in non-entry-point root schemas. If the entry point schema did **not** have `"$recursiveRoot": true"`, then `"$recursiveRef"` is evaluated exactly as if it were `"$ref"`. Its value is a URI reference, which is resolved according to the usual rules involving `"$id". ----------- The following changes were made: * schema.json, hyper-schema.json, and the additional example of hyper-operations.json (further extending hyper-schema.json) all have `"$recursiveRoot": true` * links.json does not use `"$recursiveRoot"` * The reference from each extension meta-schema to its "base" is a _normal_ `"$ref"`. Otherwise it would be an infinite loop. * All other schema references become `"$recursiveRef"`, with the same URI Reference value as before * All of the properties and $defs duplicated from schema.json to hyper-schema.json can now be removed Note that there were several odd trailing "#" fragments, which should not be present in `"$id"` in particular, so I dropped those. They are not part of this change I just found them surprising. Also, "propertyNames" had a bug. How does nobody notice this stuff? How do the meta-schemas have an apparently endless stream of bugs in them? UGH.
1 parent 5b51942 commit ea58536

File tree

4 files changed

+68
-75
lines changed

4 files changed

+68
-75
lines changed

hyper-operations.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-08/hyper-operations-FAKE#",
3+
"$id": "http://json-schema.org/draft-08/hyper-operations-FAKE",
4+
"$recursiveRoot": true,
5+
6+
"title": "FAKE DEMO JSON Hypermedia Operations FOR RECURSION EXAMPLE",
7+
"$ref": "http://json-schema.org/draft-08/hyper-schema",
8+
"properties": {
9+
"base": {
10+
"type": "string",
11+
"format": "uri-template"
12+
},
13+
"links": {
14+
"items": {
15+
"operations": {
16+
"type": "array",
17+
"items": {
18+
"type": "object",
19+
"properties": {
20+
"someKindOfSchema": { "$recursiveRef": "#" }
21+
}
22+
}
23+
}
24+
}
25+
}
26+
},
27+
"links": [
28+
{
29+
"rel": "self",
30+
"href": "{+%24id}"
31+
}
32+
]
33+
}

hyper-schema.json

Lines changed: 5 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,19 @@
11
{
22
"$schema": "http://json-schema.org/draft-08/hyper-schema#",
3-
"$id": "http://json-schema.org/draft-08/hyper-schema#",
3+
"$id": "http://json-schema.org/draft-08/hyper-schema",
4+
"$recursiveRoot": true,
5+
46
"title": "JSON Hyper-Schema",
5-
"$defs": {
6-
"schemaArray": {
7-
"allOf": [
8-
{ "$ref": "http://json-schema.org/draft-08/schema#/$defs/schemaArray" },
9-
{
10-
"items": { "$ref": "#" }
11-
}
12-
]
13-
}
14-
},
15-
"allOf": [ { "$ref": "http://json-schema.org/draft-08/schema#" } ],
7+
"$ref": "http://json-schema.org/draft-08/schema",
168
"properties": {
17-
"additionalItems": { "$ref": "#" },
18-
"additionalProperties": { "$ref": "#"},
19-
"dependencies": {
20-
"additionalProperties": {
21-
"anyOf": [
22-
{ "$ref": "#" },
23-
{ "type": "array" }
24-
]
25-
}
26-
},
27-
"items": {
28-
"anyOf": [
29-
{ "$ref": "#" },
30-
{ "$ref": "#/$defs/schemaArray" }
31-
]
32-
},
33-
"$defs": {
34-
"additionalProperties": { "$ref": "#" }
35-
},
36-
"definitions": {
37-
"$comment": "Renamed to $defs, but retained here to ensure compatibility",
38-
"additionalProperties": { "$ref": "#" }
39-
},
40-
"patternProperties": {
41-
"additionalProperties": { "$ref": "#" }
42-
},
43-
"properties": {
44-
"additionalProperties": { "$ref": "#" }
45-
},
46-
"if": {"$ref": "#"},
47-
"then": {"$ref": "#"},
48-
"else": {"$ref": "#"},
49-
"allOf": { "$ref": "#/$defs/schemaArray" },
50-
"anyOf": { "$ref": "#/$defs/schemaArray" },
51-
"oneOf": { "$ref": "#/$defs/schemaArray" },
52-
"not": { "$ref": "#" },
53-
"contains": { "$ref": "#" },
54-
"propertyNames": { "$ref": "#" },
55-
569
"base": {
5710
"type": "string",
5811
"format": "uri-template"
5912
},
6013
"links": {
6114
"type": "array",
6215
"items": {
63-
"$ref": "http://json-schema.org/draft-08/links#"
16+
"$ref": "http://json-schema.org/draft-08/links"
6417
}
6518
}
6619
},

links.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "http://json-schema.org/draft-08/hyper-schema#",
3-
"$id": "http://json-schema.org/draft-08/links#",
3+
"$id": "http://json-schema.org/draft-08/links",
44
"title": "Link Description Object",
55
"allOf": [
66
{ "required": [ "rel", "href" ] },
@@ -29,7 +29,7 @@
2929
"format": "uri-template"
3030
},
3131
"hrefSchema": {
32-
"$ref": "http://json-schema.org/draft-08/hyper-schema#"
32+
"$recursiveRef": "http://json-schema.org/draft-08/hyper-schema"
3333
},
3434
"templatePointers": {
3535
"type": "object",
@@ -55,21 +55,21 @@
5555
"type": "string"
5656
},
5757
"targetSchema": {
58-
"$ref": "http://json-schema.org/draft-08/hyper-schema#"
58+
"$recursiveRef": "http://json-schema.org/draft-08/hyper-schema"
5959
},
6060
"targetMediaType": {
6161
"type": "string"
6262
},
6363
"targetHints": { },
6464
"headerSchema": {
65-
"$ref": "http://json-schema.org/draft-08/hyper-schema#"
65+
"$recursiveRef": "http://json-schema.org/draft-08/hyper-schema"
6666
},
6767
"submissionMediaType": {
6868
"type": "string",
6969
"default": "application/json"
7070
},
7171
"submissionSchema": {
72-
"$ref": "http://json-schema.org/draft-08/hyper-schema#"
72+
"$recursiveRef": "http://json-schema.org/draft-08/hyper-schema"
7373
},
7474
"$comment": {
7575
"type": "string"

schema.json

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
{
22
"$schema": "http://json-schema.org/draft-08/schema#",
33
"$id": "http://json-schema.org/draft-08/schema#",
4+
"$recursiveRoot": true,
5+
46
"title": "Core schema meta-schema",
57
"$defs": {
68
"schemaArray": {
79
"type": "array",
810
"minItems": 1,
9-
"items": { "$ref": "#" }
11+
"items": { "$recursiveRef": "#" }
1012
},
1113
"nonNegativeInteger": {
1214
"type": "integer",
@@ -55,13 +57,13 @@
5557
},
5658
"$defs": {
5759
"type": "object",
58-
"additionalProperties": { "$ref": "#" },
60+
"additionalProperties": { "$recursiveRef": "#" },
5961
"default": {}
6062
},
6163
"definitions": {
6264
"$comment": "While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.",
6365
"type": "object",
64-
"additionalProperties": { "$ref": "#" },
66+
"additionalProperties": { "$recursiveRef": "#" },
6567
"default": {}
6668
},
6769
"title": {
@@ -101,10 +103,10 @@
101103
"type": "string",
102104
"format": "regex"
103105
},
104-
"additionalItems": { "$ref": "#" },
106+
"additionalItems": { "$recursiveRef": "#" },
105107
"items": {
106108
"anyOf": [
107-
{ "$ref": "#" },
109+
{ "$recursiveRef": "#" },
108110
{ "$ref": "#/$defs/schemaArray" }
109111
],
110112
"default": true
@@ -115,32 +117,37 @@
115117
"type": "boolean",
116118
"default": false
117119
},
118-
"contains": { "$ref": "#" },
120+
"contains": { "$recursiveRef": "#" },
119121
"maxProperties": { "$ref": "#/$defs/nonNegativeInteger" },
120122
"minProperties": { "$ref": "#/$defs/nonNegativeIntegerDefault0" },
121123
"required": { "$ref": "#/$defs/stringArray" },
122-
"additionalProperties": { "$ref": "#" },
124+
"additionalProperties": { "$recursiveRef": "#" },
123125
"properties": {
124126
"type": "object",
125-
"additionalProperties": { "$ref": "#" },
127+
"additionalProperties": { "$recursiveRef": "#" },
126128
"default": {}
127129
},
128130
"patternProperties": {
129131
"type": "object",
130-
"additionalProperties": { "$ref": "#" },
132+
"additionalProperties": { "$recursiveRef": "#" },
131133
"propertyNames": { "format": "regex" },
132134
"default": {}
133135
},
134136
"dependencies": {
135137
"type": "object",
136138
"additionalProperties": {
137-
"anyOf": [
138-
{ "$ref": "#" },
139-
{ "$ref": "#/$defs/stringArray" }
140-
]
139+
"$recursiveRef": "#"
141140
}
142141
},
143-
"propertyNames": { "$ref": "#" },
142+
"requiredDependencies": {
143+
"type": "object",
144+
"additionalProperties": {
145+
"$ref": "#/$defs/stringArray"
146+
}
147+
},
148+
"propertyNames": {
149+
"additionalProperties": { "$recursiveRef": "#" }
150+
},
144151
"const": true,
145152
"enum": {
146153
"type": "array",
@@ -162,13 +169,13 @@
162169
"format": { "type": "string" },
163170
"contentMediaType": { "type": "string" },
164171
"contentEncoding": { "type": "string" },
165-
"if": {"$ref": "#"},
166-
"then": {"$ref": "#"},
167-
"else": {"$ref": "#"},
172+
"if": { "$recursiveRef": "#" },
173+
"then": { "$recursiveRef": "#" },
174+
"else": { "$recursiveRef": "#" },
168175
"allOf": { "$ref": "#/$defs/schemaArray" },
169176
"anyOf": { "$ref": "#/$defs/schemaArray" },
170177
"oneOf": { "$ref": "#/$defs/schemaArray" },
171-
"not": { "$ref": "#" }
178+
"not": { "$recursiveRef": "#" }
172179
},
173180
"default": true
174181
}

0 commit comments

Comments
 (0)