Search code examples
scalacase-classjson4s

Scala case class whose fields can be mandatory and optional at different instances


I've created two rest end-points in akka http which takes string as input, parse it using Json4s and then do processing on it. My case class is like -

final case class A(id: String, name: String, address: String)

1st end point receives only id while the other receives all three fields and I want to use the same case class A for both. So I used default values for name & address fields like -

final case class A(id: Stirng, name: String = "", address: String = "")

This is working good for me. But now if I don't send address or name (or both) fields at second end point, it does not throw an exception stating that the name (or address) not found.

So, my question is can I create one end point in which id is mandatory while other fields does not matter and another end point where every field is mandatory using same case class ? The code to parse the string to a case class is -

parse(jsonStr).extract[A]

I hope you're getting my point.

Any suggestions ?


Solution

  • There are two ways you can achieve what you want to do.

    Option + Validations

    name and address are optional so you need to handle them.

    case class A(id: String, name: Option[String], address: Option[String])
    
    val json = """{ "id":"1" }"""
    
    // 1st endpoint
    val r = parse(json).extract[A]
    r.name.getOrElse("foo")
    r.address.getOrElse("bar")
    
    // 2nd endpoint
    val r2 = parse(json).extract[A]
    r2.name.getOrElse(/* boom! */)
    

    Default JObject + Merge

    or you can use an alternative JObject to provide default values to your input.

    case class A(id: String, name: String, address: String)
    
    val json = """{ "id":"1"  }"""
    
    val defaultValues = JObject(("name", JString("foo")), ("address", JString("bar")))
    
    // 1st endpoint
    val r = defaultValues.merge(parse(json)).extract[A]
    
    // 2nd endpoint
    val r2 = parse(json).extract[A] // boom! again