使用 Android Clean Architecture 处理来自 API 的错误和成功响应
Handling error and success response from API using Android Clean Architechture
我正在尝试在我的应用程序中实施清洁架构。我的 API 在成功和失败情况下发送响应为:
{
"data": [],
"statusCode": 200,
"statusMessage": "success",
"success": true
}
或
{
"statusCode": xxx,
"statusMessage": "Invalid Details",
"success": false
}
在之前的方法中,我使用 Retrofit 和 BaseResponse
POJO class 来处理数据场景,但在我当前的应用程序中,我使用的是带有 RxJava 和 Retrofit 的 Clean Architecture。
我将得到 Observable、Flowable 或 Single 之一作为响应,但带有 BaseResponse
作为类型。
data class BaseResponse<T>(
@SerializedName("status") val status: Boolean,
@SerializedName("statuscode") val statusCode: Int? = null,
@SerializedName("message") val message: String? = null,
@SerializedName("data") val data: T? = null
)
我正在使用 Rx 检查域中的 Rx 错误,将自定义结果作为所有结果的成功或失败:
fun <T> Single<T>.toResult(): Single<Result<T>> = this
.map { Result.Success(it) as Result<T> }
.onErrorReturn {
Result.Failure(
if (it is CompositeException) it.exceptions.last().toView()
else it.toView()
)
}
但为了处理动态响应,我无法包装它们。
我尝试了中提到的方法
How to wrap API responses to handle success and error based on Clean Architecture? 和其他几个人,但其中 none 成功了。
如何将项目包装在用例/存储库或数据层中并将它们传递给演示文稿,如 data
as Result.success 或 statusMessage
as Result.Error
如果 JSON 响应中的 data
为 null ,您可以忽略基本响应中的 <T>
并可以使用 Either<A, B>
自定义 class成功或失败案例。
你可以创造Custom Either as mentioned in here
因此您的存储库代码看起来像
fun getMyList(): Single<Either<BaseModel, CustomModel?>> =
apiClient.getList()
.map {
if (it.status.equals("success")) {
Either.Success(it.data?.toEntity())
} else {
Either.Failure(it.toEntity())
}
}
fun <T> BaseResponse<T>.toEntity() = BaseModel(
status = status,
statusCode = statusCode,
message = message
)
你的 CustomResponse.toEntity 到 CustomModel 也是如此,但是你正在做 Single<T>.toResult()
所以在你的表示层中,你可以像
.subscribe({ result ->
when (result) {
is Result.Success -> result.data.successOrFailure(::hanldeError, ::handleSuccess)
is Result.Failure -> {}
}
},{})
并分别在 hanldeError()
和 handleSuccess()
中进行操作
我正在尝试在我的应用程序中实施清洁架构。我的 API 在成功和失败情况下发送响应为:
{
"data": [],
"statusCode": 200,
"statusMessage": "success",
"success": true
}
或
{
"statusCode": xxx,
"statusMessage": "Invalid Details",
"success": false
}
在之前的方法中,我使用 Retrofit 和 BaseResponse
POJO class 来处理数据场景,但在我当前的应用程序中,我使用的是带有 RxJava 和 Retrofit 的 Clean Architecture。
我将得到 Observable、Flowable 或 Single 之一作为响应,但带有 BaseResponse
作为类型。
data class BaseResponse<T>(
@SerializedName("status") val status: Boolean,
@SerializedName("statuscode") val statusCode: Int? = null,
@SerializedName("message") val message: String? = null,
@SerializedName("data") val data: T? = null
)
我正在使用 Rx 检查域中的 Rx 错误,将自定义结果作为所有结果的成功或失败:
fun <T> Single<T>.toResult(): Single<Result<T>> = this
.map { Result.Success(it) as Result<T> }
.onErrorReturn {
Result.Failure(
if (it is CompositeException) it.exceptions.last().toView()
else it.toView()
)
}
但为了处理动态响应,我无法包装它们。
我尝试了中提到的方法 How to wrap API responses to handle success and error based on Clean Architecture? 和其他几个人,但其中 none 成功了。
如何将项目包装在用例/存储库或数据层中并将它们传递给演示文稿,如 data
as Result.success 或 statusMessage
as Result.Error
如果 JSON 响应中的 data
为 null ,您可以忽略基本响应中的 <T>
并可以使用 Either<A, B>
自定义 class成功或失败案例。
你可以创造Custom Either as mentioned in here
因此您的存储库代码看起来像
fun getMyList(): Single<Either<BaseModel, CustomModel?>> =
apiClient.getList()
.map {
if (it.status.equals("success")) {
Either.Success(it.data?.toEntity())
} else {
Either.Failure(it.toEntity())
}
}
fun <T> BaseResponse<T>.toEntity() = BaseModel(
status = status,
statusCode = statusCode,
message = message
)
你的 CustomResponse.toEntity 到 CustomModel 也是如此,但是你正在做 Single<T>.toResult()
所以在你的表示层中,你可以像
.subscribe({ result ->
when (result) {
is Result.Success -> result.data.successOrFailure(::hanldeError, ::handleSuccess)
is Result.Failure -> {}
}
},{})
并分别在 hanldeError()
和 handleSuccess()
中进行操作