使用协程解析 android 上的改造响应的最佳做法是什么
What is the best practice for parsing retrofit response on android with coroutines
我正在尝试找出处理改造响应的最佳实践。
我提供这样的改装单件:
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(AuthInterceptor())
.addInterceptor(httpLoggingInterceptor)
.build()
val retrofit = Retrofit.Builder()
.client(okHttpClient)
.baseUrl(BuildConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(CoroutinesResponseCallAdapterFactory())
.build()
val service = retrofit.create(ShowsService::class.java)
服务界面是这样的:
interface ShowsService {
@GET("popular")
suspend fun fetchPopularShows(): Response<PopularShows>
}
我从 API 获得了一个节目列表,并在存储库中像这样解析它:
override suspend fun getShows(): Result<List<Show>?> {
val shows = service.fetchPopularShows()
val body = shows.body()
val errorBody = shows.errorBody()
return when {
body != null -> {
Result.Success(body.shows)
}
errorBody != null -> {
Result.Error(Exception(errorBody.string()))
}
else -> {
Result.Error(Exception("Unknown error: ${shows.raw().message}"))
}
}
}
但是,这感觉非常非 Kotlin,并且最终可能会导致代码重复,任何人都可以指出一个以最佳实践实现的示例吗?
原则上,您可以创建一个 unwrapResponse()
通用函数,它接受一个 Response<T>
和 return 一个 Result<T?>
并合并您的算法。从眼球来看,是这样的:
suspend fun <T> unwrapResponse(response: Response<T>): Result<T> {
val body = response.body()
val errorBody = response.errorBody()
return when {
body != null -> {
Result.Success(body)
}
errorBody != null -> {
Result.Error(Exception(errorBody.string()))
}
else -> {
Result.Error(Exception("Unknown error: ${response.raw().message}"))
}
}
}
然后您可以致电 unwrapResponse(service.fetchPopularShows())
以获得 Result<PopularShows>
。
如果你真的想让 unwrapResponse()
到 return 一个 Result<List<Show>?>
,你会得到类似这样的结果:
suspend fun <T, R> unwrapResponse(response: Response<T>, unpacker: (T) -> R?): Result<R?> {
val body = response.body()
val errorBody = response.errorBody()
return when {
body != null -> {
Result.Success(unpacker(body))
}
errorBody != null -> {
Result.Error(Exception(errorBody.string()))
}
else -> {
Result.Error(Exception("Unknown error: ${response.raw().message}"))
}
}
}
unwrapResponse(service.fetchPopularShows()) { it.shows }
然后会给你 Result<List<Show>?>
.
同样,这完全是靠眼球——这里可能需要进行调整。
我正在尝试找出处理改造响应的最佳实践。
我提供这样的改装单件:
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(AuthInterceptor())
.addInterceptor(httpLoggingInterceptor)
.build()
val retrofit = Retrofit.Builder()
.client(okHttpClient)
.baseUrl(BuildConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(CoroutinesResponseCallAdapterFactory())
.build()
val service = retrofit.create(ShowsService::class.java)
服务界面是这样的:
interface ShowsService {
@GET("popular")
suspend fun fetchPopularShows(): Response<PopularShows>
}
我从 API 获得了一个节目列表,并在存储库中像这样解析它:
override suspend fun getShows(): Result<List<Show>?> {
val shows = service.fetchPopularShows()
val body = shows.body()
val errorBody = shows.errorBody()
return when {
body != null -> {
Result.Success(body.shows)
}
errorBody != null -> {
Result.Error(Exception(errorBody.string()))
}
else -> {
Result.Error(Exception("Unknown error: ${shows.raw().message}"))
}
}
}
但是,这感觉非常非 Kotlin,并且最终可能会导致代码重复,任何人都可以指出一个以最佳实践实现的示例吗?
原则上,您可以创建一个 unwrapResponse()
通用函数,它接受一个 Response<T>
和 return 一个 Result<T?>
并合并您的算法。从眼球来看,是这样的:
suspend fun <T> unwrapResponse(response: Response<T>): Result<T> {
val body = response.body()
val errorBody = response.errorBody()
return when {
body != null -> {
Result.Success(body)
}
errorBody != null -> {
Result.Error(Exception(errorBody.string()))
}
else -> {
Result.Error(Exception("Unknown error: ${response.raw().message}"))
}
}
}
然后您可以致电 unwrapResponse(service.fetchPopularShows())
以获得 Result<PopularShows>
。
如果你真的想让 unwrapResponse()
到 return 一个 Result<List<Show>?>
,你会得到类似这样的结果:
suspend fun <T, R> unwrapResponse(response: Response<T>, unpacker: (T) -> R?): Result<R?> {
val body = response.body()
val errorBody = response.errorBody()
return when {
body != null -> {
Result.Success(unpacker(body))
}
errorBody != null -> {
Result.Error(Exception(errorBody.string()))
}
else -> {
Result.Error(Exception("Unknown error: ${response.raw().message}"))
}
}
}
unwrapResponse(service.fetchPopularShows()) { it.shows }
然后会给你 Result<List<Show>?>
.
同样,这完全是靠眼球——这里可能需要进行调整。