2

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

João Menighin
  • 3,083
  • 6
  • 38
  • 80

0 Answers0