Search code examples
jsonkotlinktorkotlinx.serialization

How to get a nested specific json property with Kotlinx serialization in Ktor Kotlin without a data class?


I'm writing an web app with Kotlin and Ktor and I want to parse the json response from Google Books Api and select some specific values from it to store. For serialization I am using Kotlinx serialization. I want to avoid creating a data class

The json response from the api is nested and looks like this (Json has been shortened for clarity):

{
"kind": "books#volumes",
"totalItems": 795,
"items": [{
    "kind": "books#volume",
    "id": "zYw3sYFtz9kC",
    "etag": "ylNs2Stlgis",
    "selfLink": "https://www.googleapis.com/books/v1/volumes/zYw3sYFtz9kC",
    "volumeInfo": {
        "title": "The Contemporary Thesaurus of Search Terms and Synonyms",
        "subtitle": "A Guide for Natural Language Computer Searching",
        "authors": [
            "Sara D. Knapp"
        ],
        "publisher": "Greenwood Publishing Group",
        "publishedDate": "2000"
    }
}]
}

So how can I access the title property in this json with Kotlin / Kotlinx? I get the json object in items, but couldn't go until title.

That's my code so far after calling the api.

Routing.kt:

val response: HttpResponse = client.get("https://www.googleapis.com/books/v1/volumes?q=isbn:$isbn")
            println(response.status)
            val stringBody: String = response.body()
            val json: Map<String, JsonElement> = Json.parseToJsonElement(stringBody).jsonObject
            //println(json)
            val item = json["items"]
            //println(item)

Solution

  • You can cast JsonElement objects to more concrete types to retrieve necessary information:

    val obj = Json.parseToJsonElement(stringBody) as JsonObject
    val items = obj["items"] as JsonArray
    
    for (item in items) {
        val info = (item as JsonObject)["volumeInfo"]
        val title = (info as JsonObject)["title"].toString()
        println(title)
    }