JSON Parsing in Android: Kotlinx Serialization vs. Moshi

When an Android app queries a web API, the server transmits payloads formatted as JSON (JavaScript Object Notation). To work with this data in Kotlin, the app must deserialize the raw JSON text into typed Kotlin data classes. In this class, we compare the three primary parsers: Kotlinx Serialization, Moshi, and legacy Gson.

Parser Comparison: Kotlinx Serialization vs. Moshi vs. Gson

Dimension Google Gson (Legacy) Square Moshi (Modern) Kotlinx Serialization (Recommended)
Null-Safety Handling Dangerous! Uses Unsafe reflection; can assign null to non-nullable Kotlin properties without warning! Respects Kotlin nullability rules via Kotlin reflect/code-gen 100% Native Kotlin Type-Safe; validates nulls and defaults strictly
Performance & Code Gen Pure runtime reflection (slow startup on Android) Annotation processing (KSP) code generation (fast) Compile-time Kotlin compiler plugin (zero reflection overhead!)
Platform Support JVM / Android only JVM / Android only Multiplatform (KMP): Android, iOS, WebAssembly, Desktop

Modern Parsing with Kotlinx.Serialization

import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
import kotlinx.serialization.json.Json

@Serializable
data class UserDTO(
    @SerialName("user_id")
    val id: Int,

    @SerialName("full_name")
    val name: String,

    @SerialName("email_address")
    val email: String,

    @SerialName("is_vip")
    val isVip: Boolean = false // Default fallback if missing in JSON!
)

fun parseJsonExample() {
    val rawJson = """
        {
            "user_id": 404,
            "full_name": "Jordan Smith",
            "email_address": "jordan@veewom.com"
        }
    """.trimIndent()

    val jsonConfig = Json {
        ignoreUnknownKeys = true // Prevents crashes when backend adds new fields!
        coerceInputValues = true  // Coerces invalid nulls to default values
    }

    val user: UserDTO = jsonConfig.decodeFromString(rawJson)
    Log.d("ParsedUser", "User name: ${user.name}, VIP: ${user.isVip}")
}

Why Gson is Dangerous in Modern Kotlin Projects

Google's Gson was built for Java. It bypasses Kotlin constructors entirely by using sun.misc.Unsafe memory allocation. If a backend server sends {"email": null} for a Kotlin property declared as val email: String (non-nullable), Gson will forcefully inject null into that non-nullable field, leading to catastrophic NullPointerExceptions later in your Composables.

Frequently Asked Questions (FAQ) - Student & Interview Review

Q1. What does ignoreUnknownKeys = true do in Kotlinx.Serialization?

By default, Kotlinx Serialization throws an exception if the server returns JSON keys not modeled in your data class. Setting `ignoreUnknownKeys = true` ensures that when backend engineers add new keys, your mobile app continues to function smoothly without crashing.

Q2. How do I serialize a Kotlin object back into a JSON string?

Simply call `Json.encodeToString(myObject)`. The compiler plugin serializes the object into clean JSON format.

Q3. What is the purpose of the @SerialName annotation?

`@SerialName("server_key_name")` allows you to map backend snake_case keys (like `user_id`) to idiomatic Kotlin camelCase property names (like `val userId: Int`).

Explore Related Android Development Classes & Next Steps

Broaden your foundational and advanced Android application development skills across our curriculum:

Retrofit 2 REST API & OkHttp

Connect JSON serialization converters to HTTP client responses.

Room TypeConverters with JSON

Serialize nested lists and objects into SQLite text columns.

Kotlin Data Classes & Annotations

Define @Serializable data classes with default values.

Real-Time WebSocket Payloads

Parse incoming WebSocket text packets to Kotlin objects.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Reddit

You may also like this!