Bruno Felaco
unread,Jun 5, 2013, 10:10:02 AM6/5/13Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to json-...@googlegroups.com
Here is my scenario: in our data model, we have a mix of static and dynamically defined attributes in many of our data types. We have various entities with "built in" properties defined by the application developer, but which are also extensible by the user at run-time. The user can define the name and type of these additional attributes right from the user interface. These new attribute magically start appearing in the UI in the appropriate places. From the end-user perspective, these additional attributes are no different from the built-in attributes of the system. I would like to maintain this same illusion in our RESTful JSON based APIs by using a simple JSON Object to represent all the attributes, whether they are built-in or not. So my JSON structure should look like this:
{
"builtinProperty1" : ....,
"builtinProperty2" : .....
"customPropertyA" : ...,
"customPropertyB": ....,
...
}
I have been experimenting with Jackson for data-binding, and I am generally quite happy with the flexibility and features, so I am focusing specifically on using this tool. In order to accomplish this flexible model, I am using the @JsonAnyGetter and @JsonAnySetter annotations to store these additional properties on my objects that could not be defined at design-time in the Java class.
But the limitation of this approach is that I lose any type checking or type coercion in the deserialization process for these custom properties. From the data definition, we know that "customPropertyA" must be a number, but when using this approach, the JSON could contain a string value for that property and Jackson would happily store that value in the target object. It is then up to my back-end code to validate or parse the value to the appropriate type. This means the system may treat custom properties validation slightly different from the pre-defined properties and subtle issues will come into play. I would really prefer to be able to "teach" Jackson how to deal with these custom properties in the deserialization process so that it can do the type conversion for me and everything is consistent.
In order to communicate the definition of the data structures, I am planning to use JSON Schema. I will use the built-in Jackson model to introspect the static Java classes, and then augment that with the dynamic property definitions. This will make everything look consistent from the client perspective. What I would then like to do is feed this JSON Schema model to Jackson in the deserialization process so it can use that to produce the right data types in the dynamic property maps within the objects. When Jackson encounters a "generic" data type (such as a Map), or resorts to using the @JsonAnySetter method it would consult the JSON-Schema to produce the appropriate data type, rather than just automatically taking whatever data type was provided in the input. For example, this would be particularly useful for dates and enums, which are simply represented as strings in JSON. This feature could also be used when deserializing to a completely generic object model (using Object.class as the target type).
I have found options for validating a JSON data structure using JSON-Schema, but I have not found something that does what I just described. I do not want to run a separate validator on my input before deserializing anyway - I would prefer that deserialization and validation are done using a single pass through the input. Before I go off and code it myself, I just wanted to make sure there isn't already somebody doing something like this.