In jackson, we can uses the annotations
- @JsonTypeInfo
- @JsonSubTypes
- @JsonSubTypes.Type
to implement polymorphic serialization.
We can choose to
- Use these annotations on data model directly, this is the simplest way.
- Use these annotations on mixin. Here is a link about it Polymorphic deserialization in Jackson without annotations.
Both of these two solutions have a problem: All the sub classes must be known when writing code.
In GraphQL
- The discriminator field is fixed: "__typename"
- The sub type names are fixed too: Simple name of java classes
All the requirements are fixed, that means it unnecessary to configure sub types one by one, it's possible to create a jackson module to handle them automatically.
// An empty interface
// Developers need not to configure polymorphic metadata for any class of its subtypes
public interface GraphQLObject {}
public class BookStore implements GraphQLObject {
public List<Book> getBooks() {...}
...other gettes/setters...
}
public abstract class Book implements GraphQLObject {
... some properties ...
}
public class ElectronicBook extends Book {
... some properties ...
}
public class PaperBook extends Book {
... some properties ...
}
The usage code looks like this
BookStore store = ...;
ObjectMapper mapper = new ObjectMapper();
mapper.addModule(new GraphQLModule());
System.out.println(mapper.writeValueAsString(store));
Here, we need to create "GraphQLModule", it can handle all the sub types implement the empty interface "GraphQLObject", and tell jackson how to use the simple class name of each subtype to be the value of discriminator field "__typename"
The result should looks like:
{
name: "store",
books: [
{ __typename: "ElectronicBook", name: "book-1" },
{ __typename: "PaperBook", name: "book-2" }
]
}
Is it possible to implement the "GraphQLModule"?
Note:
Like the default polymorphic behavior of jackson, discriminator field only need to be added when the object runtime type is different with the generic type argument of list which is known when compile.