Yet another question about extends :(

1,595 views
Skip to first unread message

Hani Naguib

unread,
Oct 6, 2012, 1:34:57 AM10/6/12
to json-...@googlegroups.com
I have two schemas:
{
  "type" : "object",
  "properties" : {
    "parentProperty" : {
      "type" : "string",
      "required" : true
    }
  },
  "additionalProperties" : true
}

{
  "type" : "object",
  "extends" : {
    "$ref" : "Parent.json"
  },
  "properties" : {
    "childProperty" : {
      "type" : "string",
      "required" : true
    }
  },
  "additionalProperties" : false
}

If I validate the following json string against the Child schema it fails.
{
  "parentProperty" : "b41281",
  "childProperty" : "ru7oj"
}
error: additional properties not permitted; unwanted: ["parentProperty"]

From what I understand this fails because the 'extends' does not merge the two schemas instead it validates
the json against the two schemas and therefore fails when validating against the Child schema.

From reading some of the comments in this forum and elsewhere it seems like 'extends' will be replaced with
'allOf' but I am not clear if that will then allow me to perform the validation I am trying to do in this example.

For the time being I am getting rid of the Parent schema and simply adding its 'parentProperty' to the Child schema.

* Note that I would like to keep schemas in separate files. In my use case I can have many 'children' for any given 
'parent' and if I was to add a new property to a parent I would like to do it in one schema file.

I am hoping that someone in this forum can explain to me if the new 'allOf' (or something else) would
be able to solve this problem. 

If 'allOf' is not going to help, I think I will probably get my server to automatically merge the schemas before serving 
them. (ie when a request comes in for Child schema, it will inspect the schema, and if it 'extends' another schema it would
copy all properties from the Parent schema into the Child schema before returning it).

Chris Miles

unread,
Oct 8, 2012, 5:40:02 AM10/8/12
to json-...@googlegroups.com, Hani Naguib
It can be quite hard work to 'prove' that the extends has accessed the other schema properly. That is probably the case here. We have many examples like this but I would expect the reference to be {"$ref":"Parent.json#"} or even {"$ref":"http://www.gvmax.com:20080/json/schemas/test/Parent.json#"}.

In some validators it would be necessary to register Parent.json before referring to it.

I expect your schema and example to work.

HTH,
  Chris
--
 
 

Francis Galiegue

unread,
Oct 8, 2012, 5:49:01 AM10/8/12
to json-...@googlegroups.com, Hani Naguib
On Mon, Oct 8, 2012 at 11:40 AM, Chris Miles <ch...@moonfruit.com> wrote:
> It can be quite hard work to 'prove' that the extends has accessed the other
> schema properly. That is probably the case here. We have many examples like
> this but I would expect the reference to be {"$ref":"Parent.json#"} or even
> {"$ref":"http://www.gvmax.com:20080/json/schemas/test/Parent.json#"}.
>

In fact, a URI with an empty fragment or no fragment is equivalent. An
empty fragment is equal to the empty JSON pointer, ie the root of the
document.

> In some validators it would be necessary to register Parent.json before
> referring to it.
>
> I expect your schema and example to work.
>

Yep, they will if the implementation chooses to use the "id" value of
the root schema as the schema URI.

--
Francis Galiegue, fgal...@gmail.com
"It seems obvious [...] that at least some 'business intelligence'
tools invest so much intelligence on the business side that they have
nothing left for generating SQL queries" (Stéphane Faroult, in "The
Art of SQL", ISBN 0-596-00894-5)

Hani Naguib

unread,
Oct 8, 2012, 5:50:06 AM10/8/12
to json-...@googlegroups.com, Hani Naguib
I am using https://github.com/fge/json-schema-validator and validating Child.json does pull in Parent.json. 
If I remove the "additionalProperties" : true from Child.json and omit 'parentProperty' from the json I am validating I correctly get:
missing: ["parentProperty"]; required: ["parentProperty"]

Hani Naguib

unread,
Oct 8, 2012, 5:57:23 AM10/8/12
to json-...@googlegroups.com, Hani Naguib
Hi fge, thanks for json-schema-validator.

So, is it possible to do what I wanted to do in my example currently, or do I need to wait for a new version of the specification?

Heinrich Nirschl

unread,
Oct 8, 2012, 5:59:18 AM10/8/12
to json-...@googlegroups.com

From what I understand this fails because the 'extends' does not merge the two schemas instead it validates
the json against the two schemas and therefore fails when validating against the Child schema.

 
Yes, this is correct. The child schema specifies that there must only be the "childProperty". Since the instance must be valid according to both (parent and child) the validation fails.
 
I am hoping that someone in this forum can explain to me if the new 'allOf' (or something else) would
be able to solve this problem. 

'allOf' will not solve this problem. It has the same effect as the 'extends'.

Francis Galiegue

unread,
Oct 8, 2012, 6:23:24 AM10/8/12
to json-...@googlegroups.com, Hani Naguib
On Mon, Oct 8, 2012 at 11:57 AM, Hani Naguib <hanin...@gmail.com> wrote:
[...]
>
> So, is it possible to do what I wanted to do in my example currently, or do
> I need to wait for a new version of the specification?
>

Well, no, the newer version of the specification won't solve the problem either.

The problem is really the fact that what would be needed here is
schema merging. And this is a devil's job to define, if it is defined
at all.

The simplest workaround, which may be to your liking or not, is to
just ignore unknown members/properties in objects.

One of the reason to replace extends with allOf is to squash the
confusion which a lot of people coming from the OO world make: extends
does not merge schemas; but quite a few people expect that it does. It
is the most commonly discussed problem on this forum as far as I can
see. allOf removes the ambiguity...

benoi...@gmail.com

unread,
Jun 30, 2013, 3:37:51 PM6/30/13
to json-...@googlegroups.com, Hani Naguib
Hi Francis,

I am wondering that using the previous exemple with Parent and Child
- if I resolve the "additionnalProperty" from Child.json
- if I remove the parentProperty from the object 

When I do validate the object with the Child Schema using tiny validator 4, It returns true.
Is it correct or is it a bug with "required" additivity.

         var parent = {
             "type" : "object",
             "id" : "Parent.json",
             "required":["parentProperty"],
             "properties" : {
                 "parentProperty" : {
                     "type" : "string"
                 }
             },
             "additionalProperties" : true
         };
         
         var child =        {
             "type" : "object",
            "extends" : {
                 "$ref" : "Parent.json"
             },
             "required":["childProperty"],
             "properties" : {
                 "childProperty" : {
                     "type" : "string"
                 }
             }
         };
         
         var obj = {
             //"parentProperty" : "b41281",
             "childProperty" : "ru7oj"
         };
         
         tv4.addSchema("Parent.json", parent);
         console.log(tv4.validate(obj, child));


I understood that extends was adding constraints to a given schema, so I was expecting the validator to complain about the missing property "parentProperty". Am I wrong ?

Regards,

Francis Galiegue

unread,
Jun 30, 2013, 4:06:57 PM6/30/13
to json-...@googlegroups.com, Hani Naguib
On Sun, Jun 30, 2013 at 9:37 PM, <benoi...@gmail.com> wrote:
> Hi Francis,
>
> I am wondering that using the previous exemple with Parent and Child
> - if I resolve the "additionnalProperty" from Child.json
> - if I remove the parentProperty from the object
>
> When I do validate the object with the Child Schema using tiny validator 4,
> It returns true.
> Is it correct or is it a bug with "required" additivity.
>

The "bug" here is that "extends" does not exist anymore in draft v4 ;)
You should use allOf:


>>
>> var child = {
>> "type" : "object",
>> "extends" : {
>> "$ref" : "Parent.json"
>> },
>> "required":["childProperty"],
>> "properties" : {
>> "childProperty" : {
>> "type" : "string"
>> }
>> }
>> };
>>

should be:

{
"allOf": [
{ "$ref": "Parent.json" },
{ "type": "object", "required": [ "childProperty" ], "etc": "etc" }
]
}

--
Francis Galiegue, fgal...@gmail.com
JSON Schema in Java: http://json-schema-validator.herokuapp.com
Reply all
Reply to author
Forward
0 new messages