Comment faire du Json From/To Scala Type

12 views
Skip to first unread message

hervé DARRITCHON

unread,
Dec 13, 2015, 5:58:11 AM12/13/15
to Scala France
Salut,

J'avance doucement dans Scala en provenance de Java ;)

Je cherche un moyen simple d'avoir des objets (request/response en Json) (exposition d'une API sur web de mon service).

J'ai l'habitude d'utiliser des trucs comme Jersey (avec Jackson), Spring MVC qui sont vraiment pratique.

J'ai jeté un oeil à Play Framework (https://www.playframework.com/documentation/2.0/ScalaJsonRequests) mais ça me semble fastidieux (sur des requête/réponse longue). 
Il y a aussi Jerkson (https://github.com/codahale/jerkson) mais franchement ça ne sent pas le projet vivant ;)

Voilà, j'en appelle donc à vos expériences, qu'est ce qui est le mieux actuellement pour avoir une bonne abstraction au dessus de Json pour faire du marshalling/unmarhalling ;)

Merci d'avance.

Hervé

Jean Helou

unread,
Dec 14, 2015, 4:21:07 AM12/14/15
to hervé DARRITCHON, Scala France
Hello Hervé 

Est-ce que tu peux nous filer un poil plus d'info sur ce que tu veux faire ? En particulier l'exemple vers lequel tu pointes est dans la doc de play 2.0 et l'exemple donné dans la 2.4 (https://www.playframework.com/documentation/2.4.x/ScalaJsonHttpest déjà bien plus proche de ce que je fais en temps normal : créér des case classes permettant de modéliser ma requête/réponse puis mapper mon JSON dedans. 
Du coup pour des grosses requêtes ça devient plus facile à gérer avec de la composition et si tu as des sous arbres communs a plusieurs services tu peux envisager de réutiliser les classes de DTO (je ne dis pas que c'est forcément une bonne idée c'est du cas par cas)

Je tiens à préciser que dans l'exemple de la 2.4 ils construisent le mapping Json /case class à la main mais qu'il y a des macros pour le faire plus vite. 

Du coup une action de contrôleur typique dans mon appli ressemble à :

def myService = Action.async(parse.json) { implicit request =>
    request.body.validate[MyServiceRequest].fold(
      jsonErrors2FutureBadRequest(logger),
      _ => Future.successful(Created)
    )
 }
Sa responsabilité est de gérer la désérialisation des requêtes dans la forme dont j'ai besoin, les erreurs associées et la sérialisation des résultats du traitement (que ce soit un succès ou une erreur) Si le traitement est vraiment trivial je le laisse dans l'action du controlleur mais sinon je le délègue a un service.
Grosso modo la définition de  MyServiceRequest (souvent déclarée en privé dans la classe du controlleur ou en private[package] dans package.dtos mais là encore c'est du cas par cas) ressemble à :

case class MyServiceRequest(property1:String, property2:String,...) 
object MyServiceRequest{
  implicit val myServiceRequestFormat = Json.format[MyServiceRequest]
}

Comme perso je trouve que les macros du projet ont des limitations, j'utilise http://play-json-extra.megl.io/index.html qui gère tout un tas de trucs comme la présence de valeur par défaut ou une sérialisation plus orienté énumération pour des objets héritants de traits scellés. 

Si tel quel c'est trop verbeux il est possible d'enrichir l'action pour réduire le boilerplate : https://www.playframework.com/documentation/2.4.x/ScalaActionsComposition de mettre @JsonFormat  dans play-json-extensions ou de passer par du jackson pur comme d'habitude, éventuellement avec jerkson (pour avoir les serializers/deserializers vers les collections scala directement).
Au passage  il y a des versions de jerkson compilées pour scala 2.11 sur github (mais pas sur celui de coda hale). D'autre part, la lib n'est pas très utilisée par rapport à l'approche TypeClass mais le niveau de maintenance à faire dessus est assez faible (jackson et la lib standard scala sont des APIs stables) .Pour une boite un peu conséquente ça peut valoir le coup de maintenir et publier une version qui va vite devenir la référence quitte a demander a Hale si il est ok.

jean


--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes "Scala France".
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse scala-fr+u...@googlegroups.com.
Pour obtenir davantage d'options, consultez la page https://groups.google.com/d/optout.

hervé DARRITCHON

unread,
Dec 17, 2015, 10:20:37 AM12/17/15
to Scala France
Merci Jean.
Comme d'hab, une super réponse, précise et touffue ;)

Je suis encore un néophyte, je vais donc commencer petit à petit par le tutoriel de Play.
Effectivement, j'ai merdé ... j'ai cru Google qui m'a envoyé sur la 2.0 :(
Pas encore les bons réflexes !

Je vais regardé les macros mais pour l'instant, je n'ai rien fait dessus donc je ne sais pas comment ça marche et comment ça peut m'aider :D

En tout cas, ça a l'air comme ça plus en phase avec ce que je veux faire ;)

Jean Helou

unread,
Dec 17, 2015, 10:26:16 AM12/17/15
to hervé DARRITCHON, Scala France
Je vais regardé les macros mais pour l'instant, je n'ai rien fait dessus donc je ne sais pas comment ça marche et comment ça peut m'aider :D

Juste pour clarifier : il s'agit juste d'utiliser des macros existantes, pas d'en écrire hein... 

Ecrire les macros c'est une autre histoire, super interessante mais aussi un poil plus compliquée :)

hervé DARRITCHON

unread,
Dec 18, 2015, 9:02:27 AM12/18/15
to Jean Helou, Scala France
Yep, je viens de comprendre ... en fait, il faut suivre ce tuto (https://www.playframework.com/documentation/2.4.x/ScalaJsonInception) ?

Jean Helou

unread,
Dec 18, 2015, 9:06:14 AM12/18/15
to hervé DARRITCHON, Scala France
tout a fait :)
Reply all
Reply to author
Forward
0 new messages