1

I'm trying to define a json schema where there are multiple properties that instances of the same object for a Java application endpoint.

A simple example of what I'm trying to do is this

{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",

"properties": {
    "last": {
        "$ref": "#/$def/node"
    },
    "next": {
        "$ref": "#/$def/node"
    }
},
"$def": {
    "node": {
        "type": "object",
        "properties": {
            "item": "object"
        }
    }
}}

The issue is that when I pass this into jsonschema2pojo, it interprets this as last and next being distinct classes rather than instances of a common node object.

-----------------------------------com.example.Last.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Last {

@SerializedName("item")
@Expose
public Object item;

}

-----------------------------------com.example.Next.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Next {

@SerializedName("item")
@Expose
public Object item;

}

-----------------------------------com.example.Node.java-----------------------------------

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Node {

@SerializedName("last")
@Expose
public Last last;
@SerializedName("next")
@Expose
public Next next;

}

Is it possible to have multiple instances of a property in json-schema and would I express this? Or is this a limitation of the jsonschema2pojo tool/plugin? Or does json-schema require multiple instances be placed into an array?

Carsten
  • 2,047
  • 1
  • 21
  • 46
Jason Warner
  • 2,469
  • 1
  • 11
  • 15
  • JSON Schema relates to JSON. JSON Schema itself has nothing to do with classes or any form of code generation. Anything to do with code generation is down to the individual tool you've chosen to use. It may be it documents a specific way to do what you want, but most likely what you want is not supported. Sorry I can't be of further help. – Relequestual Mar 31 '20 at 08:00
  • There is an extension that the tool has that we could use, but requires specific entries in the schema - making it tool specific rather than generic schema. Knowing it's a tool limitation helps though. Back to the white board... – Jason Warner Mar 31 '20 at 13:09
  • Hopefully in a few years this should be easier... but yeah, a few years doesn't help you today =] – Relequestual Mar 31 '20 at 13:11
  • @JasonWarner You might have better luck if you use `definitions` instead of `$def`. In draft 2019-09, `definitions` was changed to `$defs`, but you're using draft-07. Using a non-standard keyword for definitions is probably confusing the tooling. – Jason Desrosiers Mar 31 '20 at 14:11
  • @JasonDesrosiers I tried using `definitions` in the original draft of the schema. I changed it to `$def` only after referencing the spec. It made no difference to the tool - it treated them both the same. Seems that change is only a standardizing of the convention, but not a change to the underlying functionality of mapping to a source schema. – Jason Warner Mar 31 '20 at 14:39
  • I’d also suggest to use either “$defs” or “definitions” but not “$def”. The $schema identifier for Draft 7 ends in a fragment # in most examples. Maybe fix that too. Also: adding the “jsonschema2pojo” tag on your question might attract more suitable responses. – Carsten Apr 04 '20 at 14:49
  • One more thing: the “object” String is not a valid value in “properties”. It must bei either a boolean true/false or a another schema, e.g. {} for any type. – Carsten Apr 04 '20 at 14:53
  • As it turns out, jsonschema2pojo does handle all kinds of references, i.e. while "$def" is not a standard keyword according to the JSON Schema specification it supported by jsonschema2pojo in the way you are using it. – Carsten Apr 05 '20 at 07:25

1 Answers1

1

It seems you have to force the same type being used by declaring a specific "javaType" in your definition, which is unfortunately tool-specific (which is something you wanted to avoid according to your comments).

The following worked on jsonschema2pojo.org:

Input: JSON Schema

{
  "type": "object",
  "properties": {
      "last": {
        "$ref": "#/definitions/node"
      },
      "next": {
        "$ref": "#/definitions/node"
      }
  },
  "definitions": {
      "node": {
          "javaType" : "com.example.Node",
          "type": "object",
          "properties": {
            "item": {}
          }
      }
  }
}

Output: com.example.Example.java

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Example {

    @SerializedName("last")
    @Expose
    public Node last;
    @SerializedName("next")
    @Expose
    public Node next;

}

Output: com.example.Node.java

package com.example;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Node {

    @SerializedName("item")
    @Expose
    public Object item;

}
Carsten
  • 2,047
  • 1
  • 21
  • 46