使用 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。

我将得到 ObservableFlowableSingle 之一作为响应,但带有 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() 中进行操作