I'm trying to use an interface as the RequestBody in Feign, but Feign is creating an empty object as the request. Is this not possible or am I doing something wrong here? I could not find anything on that topic so far.
This is a simplified example of what I am trying to do (in reality there are 3 different kinds of requests)
interface BookingClient {
@RequestLine("POST /booking")
@Headers("Content-Type: application/json")
fun createBooking(request: BookingRequest): BookingResponse
}
interface BookingRequest
data class NormalBooking(
val product: String
): BookingRequest
data class DiscountedBooking(
val product: String,
val discountCode: String
): BookingRequest
// Client Configuration
val client = Feign.builder()
.client(feign.okhttp.OkHttpClient())
.errorDecoder(BadEntityErrorDecoder())
.encoder(JacksonEncoder())
.decoder(JacksonDecoder(listOf(KotlinModule(), JavaTimeModule())))
.logger(feign.Logger.JavaLogger())
.logLevel(feign.Logger.Level.FULL)
.target(BookingClient::class.java, mockServer.getUrl())
If I now call createBooking()
with either implementation, Feign always serializes
{}
instead of
{
"product": "productA"
}
and
{
"product": "productA",
"discountCode": "discountCode"
}
The problem is parameter type, when we invoke Feign.target(...), Feign start to parse your BookingClient to a Http request template, and body type is BookingRequest, so Feign always serializes "{}"
interface BookingClient {
@RequestLine("POST /booking")
@Headers("Content-Type: application/json")
// BookingRequest should change to NormalBooking or DiscountedBooking
fun createBooking(request: BookingRequest): BookingResponse
}