Working with JSON in Kotlin: A Complete Guide to Parsing and Serialization
JSON (JavaScript Object Notation) remains one of the most popular data exchange formats in modern web development. When working with Kotlin, whether it's a server-side application on Ktor or a mobile app for Android, the ability to efficiently parse and serialize JSON is an essential skill. In this article, we will cover three main approaches to working with JSON in Kotlin: using the Gson, Moshi libraries, and the official solution from JetBrains — kotlinx.serialization.
Why does Kotlin require a special approach to JSON?
Kotlin is a statically typed language with features such as null-safety, data classes, and default properties. Libraries for working with JSON must account for these features to ensure the code is not only functional but also idiomatic. Incorrect configuration can lead to NullPointerException or unexpected behavior during deserialization.
1. Using Gson for Working with JSON
Gson from Google is one of the oldest and most widespread libraries. It is simple to use but has some peculiarities when working with Kotlin.
Adding the Dependency
// build.gradle.ktsimplementation("com.google.code.gson:gson:2.10.1")Serializing an Object to JSON
import com.google.gson.Gson
data class User( val id: Int, val name: String, val email: String? = null)
fun main() { val user = User(1, "Ivan Petrov", "ivan@example.com") val gson = Gson() val json = gson.toJson(user) println(json) // Output: {"id":1,"name":"Ivan Petrov","email":"ivan@example.com"}}Parsing JSON into an Object
fun parseUser(jsonString: String): User { val gson = Gson() return gson.fromJson(jsonString, User::class.java)}
fun main() { val json = """{"id":2,"name":"Anna Smirnova","email":null}""" val user = parseUser(json) println(user.name) // Anna Smirnova}Important: Gson uses Java reflection and may not account for Kotlin's null-safety. During deserialization, fields declared as non-null can receive a null value, leading to a runtime error. It is recommended to use @JvmOverloads and constructors with default values.
2. Moshi — A Modern Alternative from Square
Moshi was created with Kotlin's features in mind and offers better integration with null-safety and data classes.
Adding the Dependency
// build.gradle.ktsimplementation("com.squareup.moshi:moshi-kotlin:1.15.0")kapt("com.squareup.moshi:moshi-kotlin-codegen:1.15.0")Example of Working with Moshi
import com.squareup.moshi.Moshiimport com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
data class Product( val id: Int, val title: String, val price: Double, val inStock: Boolean = false)
fun main() { val moshi = Moshi.Builder() .addLast(KotlinJsonAdapterFactory()) .build()
val adapter = moshi.adapter(Product::class.java)
// Serialization val product = Product(101, "Laptop", 89999.99, true) val json = adapter.toJson(product) println(json) // {"id":101,"title":"Laptop","price":89999.99,"inStock":true}
// Deserialization val jsonString = """{"id":102,"title":"Mouse","price":2500.00}""" val parsedProduct = adapter.fromJson(jsonString) println(parsedProduct?.title) // Mouse println(parsedProduct?.inStock) // false (default value)}Moshi automatically handles default values in data classes and works correctly with nullable types. For better performance, it is recommended to use code generation via the @JsonClass annotation.