23

I have searched on json schema with java bindings with inheritance and all searches led me to the usage of "allOf".

Using allOf would potentially solve my problem, but I am wondering if there is a construct in json schema that I can use which will generate my java code with real java inheritance "B extends A" - rather than inlining all properties from A inside B ?

I am wondering if this is even supported / doable or I am just dreaming. If not supported, I would be curious to know the reason.

jruizaranguren
  • 12,679
  • 7
  • 55
  • 73
user3748879
  • 255
  • 1
  • 2
  • 7
  • in short, no. schemas inside `allOf`, etc. know nothing of one another and cannot be "extended" in the object-oriented sense. https://spacetelescope.github.io/understanding-json-schema/reference/combining.html – chharvey Oct 02 '17 at 01:11

3 Answers3

34

OK, well, I am the author of both:

  • the current JSON Schema validation spec;
  • and the Java library which is the most used for JSON Schema validation in Java today: json-schema-validator.

So I can answer your question, and the basic answer is no.

Why? Because there is no such thing as schema inheritance currently defined.

When using allOf, you require that all schemas in allOf match; and if you are strict about what can exist in this or that JSON, you'll have added additionalProperties to false. As such, you cannot inherit.

The real solution is a mechanism I proposed for draft v5: the $merge and $patch keywords. These would allow to patch schemas with either of RFC 7386 or RFC 6902 (see here for more info) and indeed implement schema inheritance.

In short:

  • if you set additionalProperties to false, and your basic JSON is an object, you won't be able to define additional object members;
  • with these two new keywords, you can.
fge
  • 119,121
  • 33
  • 254
  • 329
  • Thanks a lot for quick reply. I get the picture. – user3748879 Dec 10 '14 at 20:44
  • Yeah well, I am fully aware that I didn't spend the effort required to take JSON Schema to the next step, and I feel bad about it... Bug the list! – fge Dec 10 '14 at 22:39
  • @fge - `$merge` or `$patch` would actually *break* inheritance, which is why I've been fighting it. At that point, there is no theoretical connection between the two schemas A and B - instead of extending the constraints, you've patched the document that describes the constraints. As an example, you could just as easily *remove* a property from A, which flies in the face of OOP inheritance. – cloudfeet Dec 12 '14 at 13:30
  • @cloudfeet of course, you can do MORE than inheritance with both; nevertheless, it allows it and is still the cleanest solution of all solutions proposed so far. Also, many people seem to conveniently forget that JSON Schema validates all values and not just JSON Objects. – fge Dec 12 '14 at 13:32
4

"jsonschema2pojo" project contains notations for this purpose.

On the JSON schema, just include something like this;

"extendsJavaClass" : "com.somecompany.SomeBaseClass",

i.e.

{
  "title": "....",
  "description": "....",
  "type": "object",
  "extendsJavaClass" : "com.somecompany.SomeBaseClass",
  "properties": {
    "...": {
      "items": {
        "$ref": "#/definitions/...."
      },
      "type": "array"
    }
    .......
}

then the class generated by the project will have its "extends" clause as;

/**
 * ...
 * <p>
 * ...
 * 
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    ...
})
public class MyNewClass
    extends SomeBaseClass
{
...
}

Also you can search for similar notations in here.

PS: Theese notations are not "standard JSON schema constructs". They are added for the sake of "just doing it" until a standard way of doing it is possible.

Hope it helps..

myuce
  • 1,321
  • 1
  • 19
  • 29
-2

you have 3 options, I am using jsonschema2pojo : 1.0.0-alpha2

"extends": {
    "$ref": "MyObject.json"
}

or

"extends": {
    "type": "object",
    "javaType": "com.mycompany.model.MyObject"
}

or

 "extendsJavaClass" : "com.mycompany.model.MyObject"
  • 1
    So what you’re saying is: even five years later, the answer from `myuce` is still valid and there is no standard way as per Draft 2019-09. Kinda sad, but also makes sense since polymorphism works differently in different programming languages. – Carsten Apr 11 '20 at 05:44