📝
sealed class
はじめに
sealed class を初めて使ってみた内容を記事にしました。
背景
OkHttp3を使ったAPIリクエストのレスポンスを、「成功」と「失敗」で明確に分けて扱いたい場合、Kotlinのsealed classを使う設計が非常に便利です。このアプローチにより、レスポンスの管理が簡潔で明確になります。
この記事では、sealed classを使ってレスポンスを処理する方法を解説します。
実装例
1. sealed classの定義
以下のように、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を使って分岐処理を簡単に記述可能。
Kotlin標準のResult
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