How to create a call adapter for suspending functions in Retrofit?

后端 未结 3 1374
慢半拍i
慢半拍i 2020-12-05 02:35

I need to create a retrofit call adapter which can handle such network calls:

@GET(\"user\")
suspend fun getUser(): MyResponseWrapper
         


        
3条回答
  •  无人及你
    2020-12-05 03:20

    When you use Retrofit 2.6.0 with coroutines you don't need a wrapper anymore. It should look like below:

    @GET("user")
    suspend fun getUser(): User
    

    You don't need MyResponseWrapper anymore, and when you call it, it should look like

    runBlocking {
       val user: User = service.getUser()
    }
    

    To get the retrofit Response you can do the following:

    @GET("user")
    suspend fun getUser(): Response
    

    You also don't need the MyWrapperAdapterFactory or the MyWrapperAdapter.

    Hope this answered your question!

    Edit CommonsWare@ has also mentioned this in the comments above

    Edit Handling error could be as follow:

    sealed class ApiResponse {
        companion object {
            fun  create(response: Response): ApiResponse {
                return if(response.isSuccessful) {
                    val body = response.body()
                    // Empty body
                    if (body == null || response.code() == 204) {
                        ApiSuccessEmptyResponse()
                    } else {
                        ApiSuccessResponse(body)
                    }
                } else {
                    val msg = response.errorBody()?.string()
                    val errorMessage = if(msg.isNullOrEmpty()) {
                        response.message()
                    } else {
                        msg
                    }
                    ApiErrorResponse(errorMessage ?: "Unknown error")
                }
            }
        }
    }
    
    class ApiSuccessResponse(val data: T): ApiResponse()
    class ApiSuccessEmptyResponse: ApiResponse()
    class ApiErrorResponse(val errorMessage: String): ApiResponse()
    

    Where you just need to call create with the response as ApiResponse.create(response) and it should return correct type. A more advanced scenario could be added here as well, by parsing the error if it is not just a plain string.

提交回复
热议问题