Как получить и использовать ожидаемый тип ответа API в адаптере Moshi? - PullRequest
0 голосов
/ 11 июля 2020

Ниже приведены несколько упрощенных примеров 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>

Проще говоря, могло ли это работать? Если да, то приветствуются любые указатели. Или мне не хватает более простого разрешения?

Спасибо - Мэтью

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...