jsonschema-generator icon indicating copy to clipboard operation
jsonschema-generator copied to clipboard

conditionals with jackson subtype resolution

Open abhinavcode opened this issue 4 years ago • 2 comments

I have a requirement where I want to make if/else conditions for subtypes (annotated via jackson's JsonSubType.class). It could be either EXTERNAL_PROPERTY or WRAPPER_OBJECT which decides the conditionals block.

public class Animal {
  String name;
  String type;
  AnimalData animalData;
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
@JsonSubTypes({ @JsonSubTypes.Type(value = Human.class, name = "human"),
        @JsonSubTypes.Type(value = Frog.class, name = "frog"), })
public interface AnimalData{}

I want someway to get if/then blocks without traversing the final JsonNode. My expected output is:

{
   "$schema":"http://json-schema.org/draft-07/schema#",
   "type":"object",
   "properties":{
      "name":{
         "type":"string"
      },
      "type":{
         "type":"string"
      },
      "allOf":[
         {
            "if":{
               "properties":{
                  "type":{
                     "const":"human"
                  }
               }
            },
            "then":{
               "properties":{
                  "animalData":{
                     // human json 
                  }
               }
            }
         },
         {
            "if":{
               "properties":{
                  "type":{
                     "const":"frog"
                  }
               }
            },
            "then":{
               "properties":{
                  "animalData":{
                     // frog json
                  }
               }
            }
         }
      ]
   }
}

Is it possible to generate this using the jsonschema generator, without traversing the final JsonNode?

abhinavcode avatar Nov 25 '20 21:11 abhinavcode

I read #130 but it is adding constants to conditionals. I wanted some control to resolve subtype in an if condition. I tried advanced configurations but couldn't figure out a way.

abhinavcode avatar Nov 26 '20 19:11 abhinavcode

Hi @abhinavcode,

EXTERNAL_PROPERTY is a tricky one to handle generically, that's why it's not yet supported by the JacksonModule out-of-the-box. I'm open for pull requests though. 😉

However, it seems you're handling it yourself already and the main question is about not having to manually build the nested schemas once you're inside of a CustomDefinition. I've tried to document the most important methods here: https://victools.github.io/jsonschema-generator/#custom-type-definitions For this particular use-case, it sounds like createDefinitionReference()/createStandardDefinitionReference() would be an approriate choice.

As an additional reference, you could look into the JacksonModule implementation (or its JsonSubTypesResolver in particular), where the WRAPPER_OBJECT alongside some other Jackson subtype strategies are being handled.

CarstenWickner avatar Nov 26 '20 20:11 CarstenWickner