Kotlin、Retrofit、RxJava優雅実現REST API要求
3405 ワード
Retrofitは非常に強力なネットワークリクエスト案で、公式にも
REST API
各エンジニア定義のREST APIは異なりますが、基本的な考え方は同じです.異常がなければ、オブジェクトを返すか、空のオブジェクトを返すか. 要求にエラーが発生した場合、HTTPのstatusCodeは400より大きく、要求が正常である限り2 xxである. 要求エラーが発生した場合、errorBodyはエラーコードおよびエラー情報を返す.
依存の追加
NetworkException.ktの作成
ファイルを作成_Call.kt
APIインタフェースの定義
使用
同期要求
RxJava非同期要求
まとめ
このソリューションの最大の特徴は、CallメソッドをRxJavaに移行できることであり、同期リクエストがある場合もあれば、非同期リクエストがある場合もあり、複数のAPIを繰り返し定義する必要はありません.
adapter-rxjava2
ライブラリがありますが、使いにくいと思いますが、実はKotlinの拡張属性で非常に使いやすい案を実現できます.REST API
各エンジニア定義のREST APIは異なりますが、基本的な考え方は同じです.
{
"error_code":1101,
"error":" "
}
依存の追加
dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
}
NetworkException.ktの作成
class NetworkException : Exception() {
var error_code: String = ""
var error: String? = ""
override val message: String?
get() = error
}
ファイルを作成_Call.kt
fun Call.rx(): Observable {
return Observable.create {
try {
it.onNext(executeBody())
it.onComplete()
} catch (e: Exception) {
it.onError(e)
}
}.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
}
fun Call.executeBody(): T {
try {
val response = execute()
if (response.isSuccessful) {
return response.body()!!
} else if (response.errorBody() != null) {
val text = response.errorBody()!!.string()
val json = JSONObject(text)
val code = json.getString("error_code")
val error = json.getString("error")
val exception = NetworkException()
exception.error_code = code
exception.error = error
throw exception
} else {
throw Exception(" ")
}
} catch (e: Exception) {
if (e !is NetworkException) {
when (e) {
is InterruptedIOException -> throw Exception(" , ")
is JSONException -> throw Exception(" , ")
is IOException -> throw Exception(" , ")
else -> throw Exception(" ")
}
}
throw e
}
}
APIインタフェースの定義
interface AccountApiService {
@FormUrlEncoded
@POST("/account/login/phone")
fun loginPhone(@Field("phone") phone: String,@Field("code") code: String): Call
}
使用
val retrofit = Retrofit.Builder().baseUrl("http://127.0.0.1:8080")
.addConverterFactory(GsonConverterFactory.create())
.build()
val accountApiService = retrofit.create(AccountApiService::class.java)
同期要求
try {
val result = accountApiService.loginPhone("18888888888", "1234").executeBody()
println(JSON.toJSONString(result))
} catch (e: Exception) {
println(e.message)
}
RxJava非同期要求
accountApiService.loginPhone("18888888888", "1234").rx().subscribe({
println(JSON.toJSONString(it))
},{
println(e.message)
})
まとめ
このソリューションの最大の特徴は、CallメソッドをRxJavaに移行できることであり、同期リクエストがある場合もあれば、非同期リクエストがある場合もあり、複数のAPIを繰り返し定義する必要はありません.