sdk-java icon indicating copy to clipboard operation
sdk-java copied to clipboard

Polymorphic JSON deserialization with Jackson

Open mbechto opened this issue 5 months ago • 0 comments

I was wondering how to write a polymorphic parser for JSON CloudEvents, where the payload can be one of many types. Normally, with plain Jackson one can do something like this, using @JsonTypeInfo and a type field somewhere in the JSON to determine the specific class for deserialization.

In this simple example in the CloudEvent SDK docs we knew the type in advance:

PojoCloudEventData<User> cloudEventData = mapData(
    inputEvent,
    PojoCloudEventDataMapper.from(objectMapper,User.class)
);

But in my case, I would like to achieve something like the following:

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    property = "type"
)
@JsonSubTypes({
    @JsonSubTypes.Type(value = Foo.class, name = "foo"),
    @JsonSubTypes.Type(value = Bar.class, name = "bar")
})
sealed interface Payload permits Foo, Bar {}

record Foo(String str) implements Payload {}
record Bar(int i) implements Payload {}

// ...

PojoCloudEventData<Payload> cloudEventData = mapData(
    inputEvent,
    PojoCloudEventDataMapper.from(objectMapper, Payload.class)
);

Running this code, it results in an error (as expected):

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve subtype of [simple type, class Payload]: missing type id property 'type'

Because the type field is part of the CloudEvent header and/or envelope that Jackson does not know about at this point.

What's your take on this?

mbechto avatar Sep 09 '24 09:09 mbechto