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式が可能になり、本番環境での無効な状態のバグを防止できます。

試してみる — JSON to Kotlin

フルツールを開く