Parsing JSON from a resposne

I have a payload which outputs JSON

type SearchPayload {
    result: Json
}

and the JSON output is like

{
  "data": {
    "search": {
      "result": {
        "foo": {
          "bar": [
            {
              "category": "",
              "id": 1,
              "state": ""
            }
          ]
      }
    }
  }
}

When it comes to Kotlin, result is now public final val result: Any? and it is super difficult to work with Any. Is there a way to use result as a Map and List as below?

for (item in result.get("foo").get("bar")) {
   item.get("category")
}

Hi :wave:

Unfortunately, Apollo Kotlin doesn’t support generic types in custom scalar targets. Even if it did, that’d work only for the first level (Map) as anything after that could be very dynamic.

If your type has always the same shape, you could add it on a new type in your schema.

Else you’ll have to cast. I have these extensions that I reuse in such cases:

inline fun <reified T> Any?.cast() = this as T

val Any?.asMap: Map<String, Any?>
    get() = this.cast()
val Any?.asList: List<Any?>
    get() = this.cast()
val Any?.asString: String
    get() = this.cast()

Then you code becomes:

for (item in resulet.asMap.get("foo").asMap.get("bar").asList) {
  item.asMap.get("category")
}

It’s a bit more verbose but there’s no silver bullet unfortunately

1 Like

Thanks. It is a bit tedious but in general it is more of a Kotlin/Java’s problem for untyped deserialization.

1 Like