mbknor / mbknor-jackson-jsonSchema

Generate JSON Schema with Polymorphism using Jackson annotations
MIT License
234 stars 79 forks source link

Polymorphic types using property definitions #143

Open orange-buffalo opened 3 years ago

orange-buffalo commented 3 years ago

Jackson allows to define polymorphic types definitions on the properties:

@Data
public static class Container {
    private String polymorphicPropertyDefinition;

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "polymorphicPropertyDefinition")
    @JsonSubTypes({
            @JsonSubTypes.Type(value = ConcreteType1.class, name = "type_1"),
            @JsonSubTypes.Type(value = ConcreteType2.class, name = "type_2")
    })
    private AbstractType polymorphicProperty;
}

public interface AbstractType {
}

@Data
public static class ConcreteType1 implements AbstractType {
    private String value;
}

@Data
public static class ConcreteType2 implements AbstractType {
    private int value;
}

When generating a schema for Container from the example above:

@Test
void testPolymorphicType() throws JsonProcessingException {
    ObjectMapper mapper = createObjectMapper();
    JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(mapper);
    JsonNode jsonSchema = jsonSchemaGenerator.generateJsonSchema(Container.class);
    System.out.println(mapper.writeValueAsString(jsonSchema));
}

this type information is not used and oneOf is not generated:

{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "Container",
  "type" : "object",
  "additionalProperties" : false,
  "properties" : {
    "polymorphicPropertyDefinition" : {
      "type" : "string"
    },
    "polymorphicProperty" : { }
  }
}

I would expect the schema to look like this (similarly to what is generated when @JsonSubTypes is used on a class level):

{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "Container",
  "type" : "object",
  "additionalProperties" : false,
  "properties" : {
    "polymorphicPropertyDefinition" : {
      "type" : "string",
      "enum" : [ "type_1", "type_2" ]
    },
    "polymorphicProperty" : {
      "oneOf" : [ {
        "$ref" : "#/definitions/ConcreteType1"
      }, {
        "$ref" : "#/definitions/ConcreteType2"
      } ]
    }
  },
  "definitions" : {
    "ConcreteType1" : {
      "type" : "object",
      "additionalProperties" : false,
      "properties" : {
        "value" : {
          "type" : "string"
        }
      },
      "title" : "type_1"
    },
    "ConcreteType2" : {
      "type" : "object",
      "additionalProperties" : false,
      "properties" : {
        "value" : {
          "type" : "integer"
        }
      },
      "title" : "type_2"
    }
  }
}
hameno commented 10 months ago

Any update here? Not sure where to start to fix this