Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson: generate schemas with references

When using Jackson's JSON schema module, instead of serializing the complete graph I'd like to stop whenever one of my model classes is encountered, and use the class name to insert a $ref for another schema. Can you guide me to the right place in the jackson-module-jsonSchema source to start tinkering?

Here's some code to illustrate the issue:

public static class Zoo {
    public String name;
    public List<Animal> animals;
}

public static class Animal {
    public String species;
}

public static void main(String[] args) throws Exception {
    SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();

    ObjectMapper mapper = objectMapperFactory.getMapper();
    mapper.acceptJsonFormatVisitor(mapper.constructType(Zoo.class), visitor);
    JsonSchema jsonSchema = visitor.finalSchema();

    System.out.println(mapper.writeValueAsString(jsonSchema));
}

Output:

{
  "type" : "object",
  "properties" : {
    "animals" : {
      "type" : "array",
      "items" : {
        "type" : "object",
        "properties" : {          <---- Animal schema is inlined :-(
          "species" : {
            "type" : "string"
          }
        }
      }
    },
    "name" : {
      "type" : "string"
    }
  }
}

DESIRED Output:

{
  "type" : "object",
  "properties" : {
    "animals" : {
      "type" : "array",
      "items" : {
        "$ref" : "#Animal"       <----  Reference to another schema :-)
      }
    },
    "name" : {
      "type" : "string"
    }
  }
}
like image 300
dnault Avatar asked Oct 03 '13 02:10

dnault


2 Answers

Here's a custom SchemaFactoryWrapper that solves the problem. No guarantees, but it seems to work pretty well with Jackson 2.4.3.

UPDATE: With Jackson 2.5 onward it's a lot easier. Now you can specify a custom VisitorContext.

like image 194
dnault Avatar answered Oct 15 '22 17:10

dnault


You can use the HyperSchemaFactoryWrapper instead of SchemaFactoryWrapper. In this way you will get urn reference for nested entities:

HyperSchemaFactoryWrapper visitor= new HyperSchemaFactoryWrapper();
ObjectMapper mapper = objectMapperFactory.getMapper();
mapper.acceptJsonFormatVisitor(mapper.constructType(Zoo.class), visitor);
JsonSchema jsonSchema = visitor.finalSchema();

System.out.println(mapper.writeValueAsString(jsonSchema));
like image 38
cdr89 Avatar answered Oct 15 '22 16:10

cdr89