タイトルが長いですがつまり
Retrofit2 + RxJava2 という使い方をしていて、レスポンスが2xx系などの正常と4xx,5xxなどの異常なケースでパースしたいモデルクラスが違う時にどうしたらいいかという話です。
エラーレスポンスが共通なJSONとかのAPIで使えます。
よくやるServiceの書き方はこれですね
1 2 | @GET fun getUser(): Single<User> |
これを書いてあげればConverterがよしなにレスポンスをUserクラスにパースしてくれます(Gson,Moshi等ありますが本題に関係ないので割愛)
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
<< 23歳になりました。 Kotlin Android Extensionsを使ってfindViewByIdとさよならする >>
2018やぎ小屋