Ниже приведены несколько упрощенных примеров json ответов, которые я получаю из набора связанных конечных точек. Существует около 15 различных звонков / вариантов успешного ответа json. Ответ error json возвращается в том же формате, что и успех (со статусом 200), но он имеет статус «error» с сообщением об ошибке в свойстве data, которое в противном случае, в случае успеха, будет содержать ожидаемый результат. .
Примеры успешных результатов:
{"status":"ok","data":{"favourites":[{"name":"story A", "id":"123"},{"name":"story B", "id":"321"}]}}
{"status":"ok","data":{"name":"boris","age":"23"}}
Пример ошибки:
{"status":"error","data":"Error message here"}
Я знаю, что могу создать адаптер для каждого вызова API с успешным или неудачным вариантом в зависимости от статуса с подходящим типом данных. Или аналогично, например, используя polymorphi c:
PolymorphicJsonAdapterFactory.of(FavouritesResponse::class.java, "status")
.withSubtype(FavouritesResponse::class.java, Status.ok.name)
.withSubtype(FavouritesFailResponse::class.java, Status.error.name)
Но при таком подходе мне понадобится один из них для каждого из моих вызовов API, что кажется излишним. Казалось бы, имеет смысл создать адаптер типа, способный возвращать новый тип модели с обнуляемыми данными и свойствами ошибок, который может обрабатывать все мои варианты.
Итак, мои модели будут выглядеть так:
class OriginalFormat<T> {
var status: String? = null
var data: T? = null
}
class ProcessedFormat<T> {
var status: String? = null
var data: T? = null
var error: String? = null
}
, и мой адаптер будет делать что-то вроде следующего (мое понимание обработки типов generi c здесь отсутствует):
@FromJson
fun eventFromJson(incoming: OriginalFormat<T>): ProcessedFormat<T> {
val processed = ProcessedFormat<T::class.java>()
processed.status = incoming.status
if(processed.status == "ok"){
processed.error = null
processed.data = incoming.data
} else {
processed.error = incoming.data
processed.data = null
}
return processed
}
Тогда мой интерфейс API может выглядеть так:
@GET("person")
suspend fun getPerson(
@Query("id") id: Int,
): ProcessedFormat<Person>
@GET("favourites")
suspend fun getFavourites(
@Query("id") id: Int,
): ProcessedFormat<Favourites>
Проще говоря, могло ли это работать? Если да, то приветствуются любые указатели. Или мне не хватает более простого разрешения?
Спасибо - Мэтью