问题
Is "#/allOf/1/properties/body/properties/foo"
a valid $ref?
As stated in this article which explains $ref usage, it looks like it should be.
However both AJV and https://www.jsonschemavalidator.net/ seem to disagree.
Trying with a plain JSON Pointer it definitely seems to be possible: https://repl.it/repls/WretchedSpiritedMammoth
This is the schema I'm testing with.
{
"$schema": "http://json-schema.org/draft-06/schema#",
"type": "object",
"allOf": [
{
"$schema": "http://json-schema.org/draft-06/schema#",
"$id": "http:/example.org/example.schema.json",
"type": "object",
"properties": {
"type": {
"type": "string"
},
"body": {
"type": "object"
}
},
"required": [
"type",
"body"
]
},
{
"properties": {
"body": {
"$schema": "http://json-schema.org/draft-06/schema#",
"$id": "http://example.org/foo.schema.json",
"type": "object",
"properties": {
"foo": {
"type": "number",
"minimum": 1
},
"bar": {
"$ref": "#/allOf/1/properties/body/properties/foo"
}
},
"required": [
"foo",
"bar"
]
}
}
}
]
}
EDIT: These are the errors im getting:
jsonschemavalidator.net
Error parsing schema
Message: Error when resolving schema reference'#/allOf/1/properties/body/properties/foo'
. Path'allOf[1].properties.body.properties.bar'
, line .., position ..
AJV:
can't resolve reference
#/allOf/1/properties/body/properties/foo
from id http://example.org/foo.schema.json"
回答1:
Your schema is mostly right, although you've set an $id
in a subschema.
The "$id" keyword defines a URI for the schema, and the base URI that other URI references within the schema are resolved against.
https://tools.ietf.org/html/draft-handrews-json-schema-00#section-9.2
By adding an $id
to a subschema, you've reset the base URI for other URI references, which includes any use of $ref
within the subschema and its children.
$ref
...Resolved against the current URI base, it identifies the URI of a schema to use.
https://tools.ietf.org/html/draft-handrews-json-schema-00#section-8
By changing your definition of bar to the following, your schema will be valid.
"bar": {
"$ref": "#/properties/foo"
}
Further edit as Relequestual requested in his later comment:
It is valid to have an absolute URI as subschema $id, but as noted it resets the base URI. The restrictions on $id values only apply when using it to create local URI fragment identifiers (if this does not mean anything to you, do not worry about it).
Referencing a property schema from another property schema directly is valid, but the more common best practice is to put such a schema under the "definitions" keyword and have both properties refer to that location. This is what I would recommend for maximum clarity:
{
"$schema": "http://json-schema.org/draft-06/schema#",
"type": "object",
"allOf": [
{
"$schema": "http://json-schema.org/draft-06/schema#",
"$id": "http:/example.org/example.schema.json",
"type": "object",
"properties": {
"type": {
"type": "string"
},
"body": {
"type": "object"
}
},
"required": [
"type",
"body"
]
},
{
"properties": {
"body": {
"$schema": "http://json-schema.org/draft-06/schema#",
"$id": "http://example.org/foo.schema.json",
"type": "object",
"properties": {
"foo": {
"$ref": "#/definitions/whateverYouWantToCallIt"
},
"bar": {
"$ref": "#/definitions/whateverYouWantToCallIt"
}
},
"required": [
"foo",
"bar"
]
}
},
"definitions": {
"whateverYouWantToCallIt": {
"type": "number",
"minimum": 1
}
}
}
]
}
来源:https://stackoverflow.com/questions/48662513/can-a-property-of-an-allof-item-contain-a-ref-to-another-allof-items-definition