Skip to content

Instantly share code, notes, and snippets.

@nicholashagen
Created September 24, 2013 03:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicholashagen/6679965 to your computer and use it in GitHub Desktop.
Save nicholashagen/6679965 to your computer and use it in GitHub Desktop.
Thoughts on merging JAXB annotations and JSON binding annotations

Currently, there are several implementations that provide JSON to object binding in Java. Several actually use the existing JAXB annotations that are XML driven. This results in oddities that you are exposing JSON binding rules with annotations that target XML (ie: @XmlType, @XmlValue, etc). As a result, there is a future spec coming for an official JSON bindings recommendation. This will most likely result in a new set of annotations (ie: @JsonType, @JsonValue). This will end up requiring double annotations leading to metadata bloat. The problem is that despite the two being very closely tied together, there are several differences. One could argue that JSON is a subset of XML, although that is not entirely accurate.

I would propose that indeed we have two separate annotations and two separate specifications that are aligned as consistently as possible (similar named annotations for common use cases such as @XmlValue and @JsonValue). I would propose a third joint effort spec that creates an aggregation of the common cases using higher order annotations that combine the two groups of annotations. Several other Java libraries already do this such as CDI with stereotype definitions. You essentially annotate annotations to build them up as inherited annotations.

For example, consider a future class such as:

@XmlType
@JsonType
public class Customer {
    @XmlRef
    @JsonRef
    private User user;
    
    @XmlValue
    @JsonValue
    private String type;
    
    @XmlTransient
    @JsonTransient
    private transient int state;
}

This could get only worse if more media types are supported such as YAML. One could define a new set of annotations to simplify this use case. The name could probably be made much better, but I will use MediaType for now as the prefix.

@XmlValue
@JsonValue
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MediaTypeValue {
}

Now with this higher order annotation, we simply annotate:

@MediaType
public class Customer {
    @MediaTypeValue
    private String type;
}

JAXB implementations and JSON Binding implementations could both handle that as they would be able to view the MediaTypeValue annotation and reference the associated XmlValue or JsonValue type specific to that implementation.

To further this case, you can take the parts of JAXB that do not translate to JSON and utilize those annotations directly, or vice-versa. As a developer, you can view the docs for the higher order annotations and see exactly what JAXB/JSON binding annotations they are composed of in case you wanted to break it apart and be more specific.

public class Customer {
    @MediaTypeValue private String type;
    
    @XmlValue(someProperty=someValue)
    @JsonValue
    private String otherProperty;
    
    @XmlOtherAnnotations
    private Object otherValue;
}

Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment