Can a property of an allOf item contain a $ref to another allOf items definition?

[亡魂溺海] 提交于 2021-02-10 20:11:16

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!