I'm using retrofit to generate the POST requests in my simple API call:
interface IRetrofitCommService {
@POST("pushnotifications/{entityId}")
suspend fun getNotificationsAsync(
@Path("entityId") entityId: Long,
@Body model: GetNotificationsDto
): Response<List<NotificationData>>
@POST("pushnotifications")
suspend fun registerDeviceAsync(@Body model: RegisterEntityDto):
Response<RegisterEntityResultDto>
}
Note that in the second call, I have only 1 parameter, which is marked with the @Body
annotation.
Yet, when I try to use the web call, I get this exception: No annotation found for param 2
Here is my factory for creating the call:
object RetrofitFactory {
const val BASE_URL = "https://localhost:5051/api/"
fun createService(): IRetrofitCommService {
return Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(IRetrofitCommService::class.java)
}
}
Here is the DTO in question:
data class RegisterEntityDto(val name: String, val eventType: Short, val clientId: String)
Why is it looking for a 2nd parameter then? What am I missing?
CodePudding user response:
I'm not very familiar with the Retrofit and I'm doing an educated guess here, but after a short discussion in comments it seems my understanding is actually correct.
Internally, suspend
functions in Kotlin receive additional Continuation
parameter. It is always the last parameter and it is hidden from the Kotlin code. However, if we look into the generated bytecode, we'll see registerDeviceAsync()
function actually receives 2 parameters.
If some tool we use is not aware of suspend functions, it won't be able to properly interpret this additional parameter. It will just "think" registerDeviceAsync()
has two params. Retrofit added support for suspend functions in version 2.6.0
, so I guess if using older versions with suspend functions we will get exactly the behavior you faced.
You just need to update Retrofit to newer version.