Search code examples
jsonscalaparsingdeserializationjson4s

Json4s: keep unknown fields in a map when deserialising


I am trying to parse the response given by a HTTP endpoint using json4s in scala. The Json returned could have many number of fields (They are all documented and defined, but there are a lot of them, and they are subject to change.) I don't need to reference many of these fields, only pass them on to some other service to deal with.

I want to take the fields I need, and deserialise the rest to a map. The class needs to be serialised correctly also.

e.g. JSON response from endpoint:

{
 "name": "value",
 "unknown_field": "unknown",
 "unknown_array": ["one", "two", "three"],
  ...
  ... 
}

e.g. case class used in code:

case class TestResponse(name: String, otherFields: Map[String, Any])

Is there a simple solution for this?

I have made an attempt to implement a custom Serialiser for this, but have not had much luck as yet. Seems like this would be a common enough requirement. Is there a way to do this OOTB with json4s?

Cheers


Current attempt at customer serialiser:

  private object TestResponseDeserializer extends CustomSerializer[TestResponse](_ => ( {
    case JObject(JField("name_one", JString(name)) :: rest) => TestType1Response(name, rest.toMap)
    case JObject(JField("name_two", JString(name)) :: rest) => TestType2Response(name, rest.toMap)
  }, {
    case testType1: TestType1Response=>
      JObject(JField("name_one", JString(testType1.name)))
    case testType2: TestType2Response=> JObject(JField("name_two", JString(testType2.name)))
  }))

Solution

  • I was able to solve this using the custom serialiser in the original question. It didn't work for me due to an unrelated issue.