Estoy intentando modelar las respuestas de las API REST como clases de caso en las que puedo usar la coincidencia de patrones.Modelado con la clase de caso Scala
Pensé que sería una buena opción asumir la herencia, pero veo que esto está en desuso. Sé que ya hay preguntas relacionadas con las clases de casos y la herencia, pero mi pregunta es más acerca de cómo modelaría el siguiente la "forma correcta" aquí sin herencia.
Empecé con las dos clases de casos siguientes, que funcionan muy bien:
case class Body(contentType: String, content: String)
case class Response(statusCode: Int, body: Body)
es decir, una llamada REST volvería con algo como:
Response(200, Body("application/json", """{ "foo": "bar" }"""))
cual pude coincidencia de patrones como:
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. que funciona bien.
Cuando me encontré con problemas es: Me gustaría extensiones de ayuda para estas clases de casos, tales como:
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)
para que yo puedo hacer simplificado patrón coincide así:
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")
}
y que también permitiría que mi código REST se usara y devolviera directamente:
Response(code, Body(contentType, content))
que es e asier para construir una respuesta dinámicamente.
así que ...
puedo conseguirlo para compilar (con advertencias de desaprobación) a través de:
case class OK(override val body: Body) extends Response(200, body)
Sin embargo, esto no parece trabajar con la coincidencia de patrones.
Response(200, Body("application/json", "")) match {
case OK(_) => ":-)"
case _ => ":-("
}
res0: java.lang.String = :-(
¿Alguna idea sobre cómo podría funcionar esto? Estoy abierto a diferentes enfoques, pero este fue mi intento de encontrar un uso práctico para las clases de casos
Ah, gracias - Veo que me he perdido por completo el propósito de cancelar la aplicación hasta que esto; esto es muy útil. Lo probaré completamente con mi código para asegurarme de haberlo cubierto y lo aceptaré más tarde esta noche. – 7zark7
Buena respuesta @Sciss. Los extractores personalizados son una de las cosas que me gustan mucho de Scala. – mergeconflict
@ 7zark7 Tenga en cuenta que cuando utiliza extractores personalizados, pierde la exhaustividad de las clases selladas. –