Retrofit2+RxJava2を使ってレスポンスのステータスコードによってパースするモデルクラスをよしなにしたい時

Android

Posted on Nov 15


タイトルが長いですがつまり
Retrofit2 + RxJava2 という使い方をしていて、レスポンスが2xx系などの正常と4xx,5xxなどの異常なケースでパースしたいモデルクラスが違う時にどうしたらいいかという話です。
エラーレスポンスが共通なJSONとかのAPIで使えます。

よくやる書き方

よくやるServiceの書き方はこれですね

1
2
@GET
fun getUser(): Single<User>

これを書いてあげればConverterがよしなにレスポンスをUserクラスにパースしてくれます(Gson,Moshi等ありますが本題に関係ないので割愛)

200〜300の正常系とそれいがいの異常系で分けたい

retrofit2.Response<T>というのがretrofit2には含まれており、それを使うことに寄って実現できます。
正常/異常の判断はResponse#isSuccessfull()がBooleanで教えてくれるのでこれを使います。 例えばこんな感じです。

1
2
@GET
fun getUser(): Single<Response<User>>

と定義しておけば

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
service.getUser()
  .subscribeOn(Schedulers.io())
  .subscribe({
    if (it.isSuccessfull()) {
      // ここは正常系の時に来る
      // it is User

      textView.text = it.name
    } else {
      // ここは異常系の時に来る
      // it is ResponseBody
      // ナマのResponseBodyが来てるのでエラークラスにパースするなら 例えばMoshiなら

      val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
      moshi.adapter(Error::class.java).fromJson(it.errorBody()?.string())
    }
  }, { Timber.e(it) })

のように書くことができます。

何が違うか

だいたいこんなかんじ。

T Response
正常 onSuccess onSuccess
異常 onError onSuccess
API途中のエラー onError onError

まとめ

ステータスコードの正常異常でレスポンスパース変えたいけど、ResponseBodyで受けるのは嫌なときはResponse<T>をつかおう!
ホントはResponse<T, T>みたいな感じにして1つ目はisSuccessfull()なときのレスポンスモデルクラスで、2つ目はfalseの時のモデルクラスみたいにしてあげたい。

そう思ってる人居ない説。

参考

square/retfoit retrofit/Response.java at master


このエントリーをはてなブックマークに追加
comments powered by Disqus

<< 23歳になりました。     Kotlin Android Extensionsを使ってfindViewByIdとさよならする >>



2018やぎ小屋