Override property of definition included via allOf

1,859 views
Skip to first unread message

b...@benhart.co.uk

unread,
Mar 25, 2015, 6:30:44 PM3/25/15
to json-...@googlegroups.com
Hi,

I'm new to json schema but really liking it. For the life of me I can't work out if this is possible or not so hopefully someone can help out! It's related to https://groups.google.com/forum/#!topic/json-schema/86GSgHSQ0VI but not quite the same: is it possible to override one of the properties of a definition included in another definition via allOf? In my example below I want to have "c" set a maxItems on a's "errors" array. However, I can't follow the trick in that other post as whatever I try and do I get an error message "message" : "value has incorrect type (found object, expected one of [string])" (using the excellent https://json-schema-validator.herokuapp.com/syntax.jsp). I have tried lots of variations which all fail, so haven't included any of them here as the post would be very lengthy.

I have realised that having many small definitions is very flexible, so I have lots of allOf definitions such as "c" - this is a simplified example when c only has 2 in its allOf. As I'm writing this I have just thought perhaps I need to split out 'errors' from a and perhaps that would help in this case, tho I am not sure how?

Thanks in advance, and I hope the question is clear enough!

Cheers,

Ben

{
"type": "object",
"required": [
"a",
"b",
"c"
],
"definitions": {
"a": {
"type": "object",
"properties": {
"errors": {
"type": "array",
"uniqueItems": true,
"additionalItems": false,
"items": {
"type": "string"
}
}
},
"required": [
"errors"
]
},
"b": {
"type": "object",
"properties": {
"blah": {
"type": "string"
}
},
"required": [
"blah"
]
},
"c": {
"type": "object",
"allOf": [
{ "$ref": "#/definitions/a" },
{ "$ref": "#/definitions/b" }
]
}
}
}

Jason Desrosiers

unread,
Mar 27, 2015, 7:12:47 PM3/27/15
to json-...@googlegroups.com, b...@benhart.co.uk
Your example doesn't make a lot of sense.  I think there might be some conceptual gaps, or perhaps the example just got simplified a little too much.  So, changing the example as little as possible to make the schema meaningful, I would give the following as a possible solution.

{
  "type": "object",
  "allOf": [
    { "$ref": "#/definitions/a" },
    { "$ref": "#/definitions/b" },
    { "$ref": "#/definitions/c" }
  ],
  "definitions": {
    "a": {
      "type": "object",
      "properties": {
        "errors": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "string"
          }
        }
      },
      "required": ["errors"]
    },
    "b": {
      "type": "object",
      "properties": {
        "blah": {
          "type": "string"
        }
      },
      "required": ["blah"]
    },
    "c": {
      "type": "object",
      "properties": {
        "errors": {
          "type": "array",
          "maxItems": 1
        }
      }
    }
  }
}

With this schema, this would be valid.
{
  "blah": "foo",
  "errors": ["err"]
}

But this would fail because "errors" has too many items.
{
  "blah": "foo",
  "errors": ["err", "err2"]
}

However, what I think you are really trying to achieve is something more like this.
{
  "type": "object",
  "properties": {
    "blah": { "$ref": "#/definitions/blah" },
    "errors": { "$ref": "#/definitions/boundedErrors" }
  },
  "required": ["blah", "errors"],
  "definitions": {
    "errors": {
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "string"
      }
    },
    "blah": {
      "type": "string"
    },
    "boundedErrors": {
      "allOf": [{ "$ref": "#/definitions/errors" }],
      "maxItems": 1
    }
  }
}

In this example, you define your types in "definitions" and compose them in the object's "properties".  Hopefully this helps.

Jason

P.S.
"additionalItems" only has meaning when "items" is an array of schemas rather than a single schema.  That is why I removed it in my responses.

b...@benhart.co.uk

unread,
Mar 28, 2015, 2:31:12 PM3/28/15
to json-...@googlegroups.com, b...@benhart.co.uk
Hi Jason,

Many thanks for your (diplomatic!) reply, a bit of both I think. That has made things much clearer and I have been able to carry on today.

Cheers,

Ben
Reply all
Reply to author
Forward
0 new messages