JSON文字列値をKotlin Enum Classにマッピングする
固定値セットを持つJSONフィールドをKotlin enum classに変換する方法を学びます。@SerialNameアノテーション、フォールバック処理、カスタムシリアライザーを解説します。
Advanced Patterns
詳細な説明
JSON文字列からKotlin Enumへ
JSONフィールドが固定の文字列値セット("active"、"inactive"、"pending"など)のみを含む場合、Kotlinのenum classはコンパイル時の網羅性チェックを提供します。
JSONの例
{
"id": 1,
"name": "Alice",
"status": "active",
"role": "admin"
}
生成されるKotlin
@Serializable
enum class Status {
@SerialName("active") ACTIVE,
@SerialName("inactive") INACTIVE,
@SerialName("pending") PENDING
}
@Serializable
enum class Role {
@SerialName("admin") ADMIN,
@SerialName("editor") EDITOR,
@SerialName("viewer") VIEWER
}
@Serializable
data class User(
val id: Int,
val name: String,
val status: Status,
val role: Role
)
なぜEnumなのか?
enum的フィールドにStringを使用すると、タイプミスでもコンパイルが通ります。enum classでは:
when (user.status) {
Status.ACTIVE -> enableFeatures()
Status.INACTIVE -> showReactivation()
Status.PENDING -> showVerification()
// ケースが漏れるとコンパイラが警告!
}
JSONマッピングの@SerialName
@SerialNameはJSON文字列をKotlin enum定数にマッピングします。これがないと、kotlinx.serializationはenum定数名そのもの("ACTIVE")を期待しますが、小文字のAPI値と一致することはまれです。
未知の値の処理
APIは時間の経過とともに新しいenum値を追加する可能性があります。カスタムシリアライザーで未知の値を優雅に処理します:
@Serializable
enum class Status {
@SerialName("active") ACTIVE,
@SerialName("inactive") INACTIVE,
@SerialName("pending") PENDING,
UNKNOWN;
companion object {
fun fromJson(value: String): Status =
entries.find { it.name.equals(value, ignoreCase = true) } ?: UNKNOWN
}
}
Gsonアプローチ
enum class Status {
@com.google.gson.annotations.SerializedName("active") ACTIVE,
@com.google.gson.annotations.SerializedName("inactive") INACTIVE,
@com.google.gson.annotations.SerializedName("pending") PENDING
}
EnumはKotlinコードを自己文書化し、無効な状態から保護します。これはランタイムクラッシュがユーザーを苛立たせるAndroidアプリで特に価値があります。
ユースケース
モバイルアプリやバックエンドサービスはAPIからステータスフィールド、ロールタイプ、カテゴリ値を頻繁に受け取ります。Kotlin enumにマッピングすることで、網羅的なwhen式が可能になり、本番環境での無効な状態のバグを防止できます。