I'm integrating with an API that responses with the follwing format:
{
status: {
status: 200,
response_code: "SUCCESS",
// ...
},
data: {
//...
}
}
The data
part can be an object or list of objects.
To work with it I have created a nice generic class:
data class ApiResponseDTO<T> (
@JsonProperty("status")
val status: ResponseStatusDTO,
@JsonProperty("data")
val dataAny: T?
)
Then I could use it in my Feign Client as:
@GetMapping("/foo")
fun foo(): ApiResponse<SomeDataObject>
@GetMapping("/bar")
fun bar(): ApiResponse<List<SomeDataObject>>
Everything was working fine until I found an inconsistency in this API. When the requested endpoint doesn't return anything, it always return an empty array []
.
So a request that returns something like:
// Foo response
{
status: {
// ...
},
data: {
foo: "bar"
}
}
Returns the following if it has no data to show:
// Foo response
{
status: {
// ...
},
data: []
}
This of course breaks my serialization/deserialization because I was always expecting a return of ApiResponse<FooObject>
and suddenly I get a ApiResponse<List<FooObject>>
I'm looking for an elegant way to work around this scenario. I was thinking something like:
data class ApiResponseDTO<T> (
@JsonProperty("status")
val status: ResponseStatusDTO,
@JsonSetter("data")
val dataJson: JsonNode
) {
@get:JsonGetter("data")
val data: T?
get() {
val om = ObjectMapper()
return // Check wheter the JsonNode is an empty array and my T is not a Collection type and return null
// Otherwise, use ObjectMapper to deserialize the dataJson into my T object
}
}
Problem is I cannot get T
type at runtime because of the erasing, so I can't find a way to deserialize it with ObjectMapper
.
I also tried writing a custom StdDeserializer
for the data
field, but couldn't find a way to make it work with generics :s
Thanks in advance