Dans le cadre d’un petit projet personnel de dessin de graphes, j’ai eu l’occasion de jouer avec le framework Play! C’est le framework web « hype » du moment dans l’écosystème Java. Avec le module Scala ajoutant la touche fonctionnelle, la productivité est au rendez vous. Un court billet pour vous parler de la solution de serialization Json mise en oeuvre.
Play! est un framework web pour Java avec le vent en poupe. Il est constitué d’une stack complète, pas besoin de conteneur de servlet ni de serveur d’application. C’est léger, rapide, stateless et ca s’inspire très fortement de Rails. On y trouve tout ce dont on a besoin pour développer des applications web : système de templating, ORM (Hibernate), cache, un système de plugin et une communauté fleurissante. Le système de template du module Scala est plutôt cool : un template est une fonction à laquelle on passe des paramètres qui retourne du Html. Nos templates s’imbriquent les uns dans les autres via des appels de fonctions : avec la compilation et typage statique c’est puissant !
J’ai suivi le tutoriel de James Ward pour le setup du projet dans IntelliJ (on peut développer avec un editeur de texte, mais à mon gout ca ne remplace pas un puissant IDE).
L’exposition de services RESTFull est triviale avec Play!. Le client HTML5 + Js avec JQuery fait ses appels asynchrones et consomme les services en question. Rapidement, le besoin d’une solution pour serializer des graphes d’objets au format Json s’est fait sentir. Après quelques tests je suis tombé sur le JsonDSL de lift-json pour faire du Json en Scala.
La dépendance à ajouter dans votre dependencies.yml est la suivante :
require : - ... - net.liftweb -> lift-json_2.8.1 2.2
Voici un exemple de serialization d’une instance de Graphe :
def toJson: JObject = { import net.liftweb.json.JsonDSL._ ("nodes", nodeToPosition.toList.map { n => (("label", n._1.name) ~ ("x", n._2.apply(0)) ~ ("y", n._2.apply(1)) ~ ("weight", n._1.weight) ~ ("anchor",n._1.isFixed)) }) ~ ("edges", edges.map { e => (("source", e.startNode.name) ~ ("target", e.endNode.name) ~ ("length", e.weight)) }) }
L’opérateur « ~ » , équivalent sémantique de la méthode « .~() » permet de construire très simplement la structure de son objet Json.
Ensuite dans le controller on retourne le resultat comme suit :
package controllers import play.mvc._ import net.liftweb.json.JsonAST import net.liftweb.json.Printer._ import models.ForceDirectedLayout object Graphs extends Controller { def show(id:String, w:Int = 860, h:Int = 600) = { val layout = new ForceDirectedLayout(id).execute(100).scale(w,h) Json(compact(JsonAST.render(layout.toJson))) } }
Ce qui produit des documents Json de cette forme ci :
Si vous avez connaissance d’une meilleure technique je suis preneur, avec Jackson ou Gson par exemple.
Pour terminer je voulais pousser la webapp sur Heroku (suite à leur annonce réjouissante) en suivant le tuto de James Ward toujours.
Un petit git push heroku master mais je reste bloqué sur le message suivant :
Counting objects: 154, done. Delta compression using up to 2 threads. Compressing objects: 100% (143/143), done. Connection to 10.86.82.54 closed by remote host.KiB/s error: pack-objects died of signal 13 error: failed to push some refs to 'git@heroku.com:taraxe.git'
A suivre donc…
A venir dans un prochain billet, je ferai une revue de la nouvelle édition du livre Apache Maven 2 et 3 de Nicolas De Loof et Arnaud Héritier.