I'm attempting to model responses from REST APIs as case classes which I can use pattern matching on.
I thought it would be a good fit assuming inheritance, but I see that this is deprecated. I know there are already questions related to case classes and inheritance, but my question is more about how you would model the following the "right way" here without inheritance.
I started with the following two case classes, which work fine:
case class Body(contentType: String, content: String)
case class Response(statusCode: Int, body: Body)
i.e. a REST call would return with something like:
Response(200, Body("application/json", """{ "foo": "bar" }"""))
which I could pattern match like:
response match {
case Response(200, Body("application/json", json)) => println(json)
case Response(200, Body("text/xml", xml)) => println(xml)
case Response(_,_) => println("Something unexpected")
}
etc. which works fine.
Where I ran into trouble is: I'd like helper extensions for these case classes, such as:
case class OK(body: Body) extends Response(200, body)
case class NotFound() extends Response(404, Body("text/plain", "Not Found"))
case class JSON(json: String) extends Body("application/json", json)
case class XML(xml: String) extends Body("text/xml", xml)
so that I can do simplified pattern matches like this:
response match {
case OK(JSON(json)) => println(json)
case OK(XML(xml)) => println(xml)
case NotFound() => println("Something is not there")
// And still drop down to this if necessary:
case Response(302, _) => println("It moved")
}
and also which would also allow my REST code to directly use and return:
Response(code, Body(contentType, content))
which is easier to build a response dynamically.
so...
I can get it to compile (with deprecation warnings) via:
case class OK(override val body: Body) extends Response(200, body)
However, this doesn't seem to work with pattern matching.
Response(200, Body("application/json", "")) match {
case OK(_) => ":-)"
case _ => ":-("
}
res0: java.lang.String = :-(
Any ideas on how this could work? I'm open to different approaches, but this was my attempt to find a practical use for case classes