📝
sealed class
はじめに
sealed class
を初めて使ってみた内容を記事にしました。
背景
OkHttp3を使ったAPIリクエストのレスポンスを、「成功」と「失敗」で明確に分けて扱いたい場合、Kotlinのsealed class
を使う設計が非常に便利です。このアプローチにより、レスポンスの管理が簡潔で明確になります。
この記事では、sealed class
を使ってレスポンスを処理する方法を解説します。
実装例
sealed class
の定義
1. 以下のように、ApiResponse
というsealed class
を定義します。
sealed class ApiResponse<out T> {
data class Success<out T>(val data: T) : ApiResponse<T>()
data class Error(val errorCode: Int, val message: String? = null) : ApiResponse<Nothing>()
}
-
Success
クラスは、成功した場合のデータをラップします。 -
Error
クラスは、エラーコードとエラーメッセージを保持します。
2. APIクライアントの実装
OkHttp3を使ったAPIリクエストをラップするApiClient
クラスを実装します。
import okhttp3.*
import java.io.IOException
class ApiClient(private val client: OkHttpClient) {
fun <T> makeRequest(
request: Request,
responseParser: (String) -> T?,
callback: (ApiResponse<T>) -> Unit
) {
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
callback(ApiResponse.Error(500, e.message))
}
override fun onResponse(call: Call, response: Response) {
if (response.isSuccessful) {
val body = response.body?.string()
val parsedData = body?.let { responseParser(it) }
if (parsedData != null) {
callback(ApiResponse.Success(parsedData))
} else {
callback(ApiResponse.Error(400, "Parsing error"))
}
} else {
callback(ApiResponse.Error(response.code, response.message))
}
}
})
}
}
ポイント
- 成功時には
ApiResponse.Success
を返します。 - エラー時には
ApiResponse.Error
を返し、HTTPステータスコードやエラーメッセージを含めます。
3. 使用例
実際にApiClient
を使ってAPIリクエストを行う例です。
fun main() {
val client = OkHttpClient()
val apiClient = ApiClient(client)
val request = Request.Builder()
.url("https://api.example.com/data")
.build()
apiClient.makeRequest(
request,
responseParser = { body -> body }, // ボディをそのまま返す例
) { response ->
when (response) {
is ApiResponse.Success -> {
println("Success: ${response.data}")
}
is ApiResponse.Error -> {
println("Error: Code=${response.errorCode}, Message=${response.message}")
}
}
}
}
sealed class
が便利なのか?
なぜ- 型安全: 成功と失敗のケースを明確に分けられるため、適切にハンドリングできます。
-
拡張性: 必要に応じて新しいケース(例:
Loading
)を追加できます。 -
簡潔な記述: 呼び出し側で
when
を使って分岐処理を簡単に記述可能。
Result
Kotlin標準のKotlin標準で Result
というものが用意されている...!!
result.fold(
onSuccess = { data -> println("Success: $data") },
onFailure = { error -> println("Error: ${error.message}") }
)
まとめ
sealed class
を使うことで、OkHttp3のレスポンスをわかりやすく管理できるようになります。特に、成功と失敗を型で区別したい場合に最適です。
もっと早く知りたかった... ^^;
参考文献
- Kotlinのsealed classを使いこなす
https://qiita.com/kikuchy/items/ad89a12029082be8d218
Discussion