Schema Type Hierarchy

643 views
Skip to first unread message

ddarios

unread,
Sep 14, 2012, 4:15:04 PM9/14/12
to json-...@googlegroups.com
Hi, I am working on a project where I need to create a Json Schema for Java classes. I am having a hard time setting up my schema when in comes to class hierarchy.

Lets say I have a class called Animal which has only a "name" field. Then I create two sub-classes, Dog and Cat. Dog has a field called "breed" and cat has a field called "toy". Finally I have a class called Zoo that has a list of animals.

Now, I want to create a schema for Dog. Dog should accept all attributes from animal ("name") plus it's own attribute ("breed"). How can I go about doing this without duplicating the name field under the dog's properties? I figure in some way I need to reference the Animal schema but I don't know exactly how to do this. Can you please point me in the right direction? Also, I want to specify that the Zoo can only contain type Animal in my schema. Is there a way I can do this? Thank you in advance for the help.

{
    "id": "dog",
    "type": "object",
    "properties": {
        "breed": {
            "type": "string"
        }
    }

}

{
    "id": "animal",
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        }
    },
    "additionalProperties":false
}

Francis Galiegue

unread,
Sep 14, 2012, 4:57:17 PM9/14/12
to json-...@googlegroups.com
Hello,
Unfortunately, you will encounter several problems:

1. inheritance is possible with the "extends" keyword, as in:

{
"schema": "for",
"cat": "here",
"extends": { "$ref": "#/animal" }
}

but in "animal", you define additionalProperties as being false. Which
means your cat will be invalid whatever you do. "extends" means that
all constraints in "animal" have to be obeyed _in addition_ to all
constraints in "cat", but it does not merge schemas. If you remove
additionalProperties, however, this problem goes away. Just ignore
unknown object members ;)

2. it looks like you want to have schemas in separate files: how do
you intend to load them, and then address them? "id" is fraught with
problems as it is currently defined, and no two implementations act
the same with regards to this keyword...

--
Francis Galiegue, fgal...@gmail.com
JSON Schema: https://github.com/json-schema
"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)

Francis Galiegue

unread,
Sep 14, 2012, 5:03:21 PM9/14/12
to json-...@googlegroups.com
Oh, and I forgot about the zoo.

If I were you, I'd put everything in a same schema and use JSON
Pointer for addressing -- this is the only guarantee currently of
unambiguous addressing. Ie:

{
"description": "zoo",
"type": "array",
"items": { "$ref": "#/anyAnimal" },
"minItems": 1,

"anyAnimal": {
"type": [ { "$ref": "#/cat" }, { "$ref": "#/dog" } ],
},

"cat": {
"extends": { "$ref": "#/animal" },
"whateverelse": "isneeded"
},

"dog": {
"extends": { "$ref": "#/animal" },
"whateverselse": "isneeded"
},

"animal": {
"schema": "for",
"animal": "here"

Eric Stob

unread,
Sep 14, 2012, 5:04:02 PM9/14/12
to json-...@googlegroups.com
Sorry to say this but I think you should consider xsd instead.


--
 
 

Francis Galiegue

unread,
Sep 14, 2012, 5:07:42 PM9/14/12
to json-...@googlegroups.com
On Fri, Sep 14, 2012 at 11:04 PM, Eric Stob <eric...@blekko.com> wrote:
> Sorry to say this but I think you should consider xsd instead.
>

This is really not on topic at all :/

ddarios

unread,
Sep 14, 2012, 5:40:22 PM9/14/12
to json-...@googlegroups.com
Thanks for the reply.

The reason I put had additionalProperties be false is for validation purposes. When I go to validate a Json String against the schema, it will pass even if there is garbage in the string. I guess the way to avoid this is to use the required field to specify what is required. In this case if I make "name" required in Animal and and have Dog extend Animal, will this inherently make the name field required when I am doing a validation? Namely, will the validation check to make sure Dog has the required fields of it's parent schema?

I plan on storing the schemas in separate files as of right now. How would you suggest I store them as to reference them properly? I've tried referencing the schemas using the syntax you have written and I get a dangling JSON Reference. The only other way I have been able to reference properly is through a URI but I rather store on my local machine and reference the files.  

Francis Galiegue

unread,
Sep 14, 2012, 5:52:37 PM9/14/12
to json-...@googlegroups.com
On Fri, Sep 14, 2012 at 11:40 PM, ddarios <vidio...@gmail.com> wrote:
> Thanks for the reply.
>
> The reason I put had additionalProperties be false is for validation
> purposes. When I go to validate a Json String against the schema, it will
> pass even if there is garbage in the string. I guess the way to avoid this
> is to use the required field to specify what is required. In this case if I
> make "name" required in Animal and and have Dog extend Animal, will this
> inherently make the name field required when I am doing a validation?
> Namely, will the validation check to make sure Dog has the required fields
> of it's parent schema?
>

It is not Dog that will, but Animal. So, yes. It is important to
understand that your base schema, and the one(s) in "extends" (because
you _can_ put several schemas in "extends"), are validated
independently.

> I plan on storing the schemas in separate files as of right now. How would
> you suggest I store them as to reference them properly? I've tried
> referencing the schemas using the syntax you have written and I get a
> dangling JSON Reference. The only other way I have been able to reference
> properly is through a URI but I rather store on my local machine and
> reference the files.
>

Hmm, would you happen to be using my implementation by any chance
(https://github.com/fge/json-schema-validator)? That vocabulary rings
a bell :p

If yes, would you mind opening an issue there with your sample code,
schemas _and_ the version you use?

Cheers,

ddarios

unread,
Sep 14, 2012, 6:15:26 PM9/14/12
to json-...@googlegroups.com
Yep I'm using your implementation :-P So when you say that they are validated separately, does that mean I have to validate one then validate the other? It seems that way because I have use extends to extend Animal to Dog and run the validation, but I am not getting any complaints if I remove the "name" which is required for Animal. I am using pastebin to host my schema for now since I can get a reference from the url

{
    "animal": {
        "id": "animal",
        "type": "object",
        "properties": {
            "name": {
                "type": "string",
                "required": true
            }
        }
    }
}

{
"dog": {

"id": "dog",
"type": "object",
        "extends": {
"$ref": "http://pastebin.com/raw.php?i=3gFPBk32"
},
"properties": {
"breed": {
"type": "string",
"required": true
}
}
}
}

{"breed":"red","name":"bob"} -->Success
{"breed":"red"} -->Success but should fail
{"name":"bob"} --> Fail because breed is required

Francis Galiegue

unread,
Sep 14, 2012, 6:23:35 PM9/14/12
to json-...@googlegroups.com
On Sat, Sep 15, 2012 at 12:15 AM, ddarios <vidio...@gmail.com> wrote:
> Yep I'm using your implementation :-P

I knew this vocabulary looked familiar ;)

> So when you say that they are
> validated separately, does that mean I have to validate one then validate
> the other?

No, what I mean is that the schema in "extends" is processed
completely independently of the rest of the keywords.

> It seems that way because I have use extends to extend Animal to
> Dog and run the validation, but I am not getting any complaints if I remove
> the "name" which is required for Animal. I am using pastebin to host my
> schema for now since I can get a reference from the url
>

You have just given me an idea for a new feature -- a schema bundle.

> {
> "animal": {
> "id": "animal",
> "type": "object",
> "properties": {
> "name": {
> "type": "string",
> "required": true
> }
> }
> }
> }
>
> {
> "dog": {
>
> "id": "dog",
> "type": "object",
> "extends": {
> "$ref": "http://pastebin.com/raw.php?i=3gFPBk32"
> },
> "properties": {
> "breed": {
> "type": "string",
> "required": true
> }
> }
> }
> }
>

Your pastebin is equivalent to an empty schema: it starts with

{
"animal": { etc etc }
}

So, this is expected. Either put the schema within animal as the
pastebin or use "http://pastebin.com/raw.php?i=3gFPBk32#/animal" as
$ref (ie, the content at that URI, and look up JSON Pointer #/animal).

ddarios

unread,
Sep 14, 2012, 6:43:23 PM9/14/12
to json-...@googlegroups.com
WOW! I was missing the JSON Pointer! I think that is what I was looking for, thanks! I was able to get it to validate fine using the pointer extension.

As for the syntax issue, I am pretty sure I was getting this issue because I wasn't wrapping my entire schema with curly braces "{ }" therefore the pointer probably didn't know what to reference. I am still trying to figure out how to do validation when there are multiple schemas in the same file because when I validate this way, I get a success every time (unless the additionalProperties is false). I believe this is because the Json string I am validating is going against the entire schema and not the individual schemas inside. For example

"parent" = {

"schema1":{ },
"schema2":{ },
"schema3":{ }

}

It seems any string will be validated against the parent properties and not the individual schema properties. Since there are no properties it automatically is a success. How would I go about putting keeping the schemas together for referencing and still be able to validate a string against the parent schema?

Francis Galiegue

unread,
Sep 14, 2012, 6:57:38 PM9/14/12
to json-...@googlegroups.com
On Sat, Sep 15, 2012 at 12:43 AM, ddarios <vidio...@gmail.com> wrote:
> WOW! I was missing the JSON Pointer! I think that is what I was looking for,
> thanks! I was able to get it to validate fine using the pointer extension.
>
> As for the syntax issue, I am pretty sure I was getting this issue because I
> wasn't wrapping my entire schema with curly braces "{ }"

If you were not doing so, that would not even have been valid JSON,
and the API would have failed sooner than that, correct?

> [...] I am still trying to figure
> out how to do validation when there are multiple schemas in the same file
> because when I validate this way, I get a success every time
>

It depends on what version of the API you use but it is possible.

With 1.0.x:

http://fge.github.com/json-schema-validator/old/org/eel/kitchen/jsonschema/main/JsonSchemaFactory.html#createSchema(org.eel.kitchen.jsonschema.ref.SchemaContainer,
java.lang.String)

With 1.2.x:

http://fge.github.com/json-schema-validator/stable/org/eel/kitchen/jsonschema/main/JsonSchemaFactory.html#fromSchema(com.fasterxml.jackson.databind.JsonNode,
java.lang.String)

(the method in 1.0.x also works in 1.2.x but is deprecated)

Francis Galiegue

unread,
Sep 14, 2012, 7:00:01 PM9/14/12
to json-...@googlegroups.com
On Sat, Sep 15, 2012 at 12:57 AM, Francis Galiegue <fgal...@gmail.com> wrote:
[...]
Argh! Links cut. You'll have to copy/paste them I'm afraid... Sorry!

ddarios

unread,
Sep 14, 2012, 7:51:46 PM9/14/12
to json-...@googlegroups.com
Perfect! Thank you very much for your information and quick reply. This is all the info I needed to do what I needed to do. Thanks again.

ddarios

unread,
Sep 14, 2012, 7:59:53 PM9/14/12
to json-...@googlegroups.com
Sorry one more question... Do you have a maven repository for the 1.2.0 stable version? I was able to find the 1.0.4 version even though the maven repo site says only 0.4 and 0.5beta are the available ones. Thanks.


On Friday, September 14, 2012 4:00:02 PM UTC-7, fge wrote:
Reply all
Reply to author
Forward
0 new messages