Sto tentando di modellare le risposte dalle API REST come classi di casi su cui è possibile utilizzare la corrispondenza del modello.Modellazione con classe caso Scala
Ho pensato che sarebbe stata una buona idea assumendo l'ereditarietà, ma vedo che questo è deprecato. So che ci sono già domande relative a case case ed ereditarietà, ma la mia domanda è più su come modellerai il seguente "giusto modo" qui senza ereditarietà.
ho iniziato con le seguenti due classi case, che funzionano bene:
case class Body(contentType: String, content: String)
case class Response(statusCode: Int, body: Body)
cioè una chiamata REST sarebbe tornato con qualcosa di simile:
Response(200, Body("application/json", """{ "foo": "bar" }"""))
che potevo modello partita come:
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")
}
ecc. Che funziona bene.
Dove mi sono imbattuto nei guai è: Vorrei estensioni di supporto per queste classi di casi, come ad esempio:
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)
in modo che io possa fare semplificato modello corrisponde in questo modo:
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")
}
e inoltre che consentirebbe anche al mio codice REST di utilizzare e restituire direttamente:
Response(code, Body(contentType, content))
che è e asier per costruire una risposta in modo dinamico.
così ...
posso farlo per compilare (con avvisi deprecazione) tramite:
case class OK(override val body: Body) extends Response(200, body)
Tuttavia, questo non sembra funzionare con pattern matching.
Response(200, Body("application/json", "")) match {
case OK(_) => ":-)"
case _ => ":-("
}
res0: java.lang.String = :-(
Qualche idea su come potrebbe funzionare? Sono aperto a diversi approcci, ma questo è stato il mio tentativo di trovare un utilizzo pratico per le classi di casi
Ah, grazie - Vedo che mi sono totalmente perso lo scopo di inapplicare fino a questo; questo è molto utile. Verificherò tutto questo con il mio codice per assicurarmi di aver coperto e accetterò più tardi stasera. – 7zark7
Buona risposta @Sciss. Gli estrattori personalizzati sono una delle cose che mi piace molto di Scala. – mergeconflict
@ 7zark7 Si noti che quando si utilizzano estrattori personalizzati si perdono garanzie esaustive di classi sigillate. –