Search code examples
javajsonjacksonjsonschemajava-record

Json schema with anyOf field to java record


How can I generate java record objects for java schemas with the anyOf field?

I have the following schemas:

animals.json

{
    "type": "object",
    "properties": {
        "animals": {
            "type": "array",
            "items": {
                "anyOf": [
                    {"$ref": "mammale.json"},
                    {"$ref": "bird.json"}
                ],
                "minContains": 1,
                "uniqueItems": true
            }
        }
    }
}

mammal.json

{
    "type": "object",
    "properties": {
        "mammalType": {"type": "string"},
        "furColor": {"type": "string"}
    }
}

bird.json

{
    "type": "string"
}

I want to output a json that looks like the following:

{
    "animals": [
        {
            "mammalType": "dog",
            "furColour": "brown"
        },
        "someBirdsName"
    ]
}

Is there a recommended way to represent the 'anyOf' structure in the java records (preferably with Jackson annotation)?

I found a solution when using POJOs, where they use an interface: Json schema with anyOf fields to POJO

This looks like a good solution but how do I us an arbitrary string that doesnt implements the interface?


Solution

  • To produce json like the following:

    {
      "animals" : [ {
        "mammalType" : "dog",
        "furColour" : "brown"
      }, 
        "someString"
      ]
    }
    

    Which corresponds to schema like this:

    {
        "type": "object",
        "properties": {
            "animals": {
                "type": "array",
                "items": {
                    "anyOf": [
                        {"$ref": "mammale.json"},
                        {"type": "String"}
                    ],
                    "minContains": 1,
                    "uniqueItems": true
                }
            }
        }
    }
    

    Then the following will do it:

    public record ResponseServiceAlgolia(Object[] animals) {}
    
    public record Mammal(String mammalType, String furColour) {}
    
    public static void main(String[] args) throws JsonProcessingException {
        
        Mammal mammal = new Mammal("dog", "brown");
        
        Object[] animals = new Object[] {mammal, "someString"};
        ResponseServiceAlgolia responseServiceAlgolia = new ResponseServiceAlgolia(animals);
        
        ObjectMapper objectMapper = JsonMapper.builder().enable(SerializationFeature.INDENT_OUTPUT).build();
        
        var json = objectMapper.writeValueAsString(responseServiceAlgolia);
        System.out.println(json);
    
    }
    

    Output:

    {
      "animals" : [ {
        "mammalType" : "dog",
        "furColour" : "brown"
      }, "someString" ]
    }