Devoxx: Play! Framework 2.0

Deuxième retour de la conférence Devoxx qui bat en ce moment même son plein à Anvers en Belgique. J’ai assisté hier matin à la session sur Play! Framework 2.0 animée par Guillaume Bort et Sadek Drobi.

Introduction

Pour ceux qui ne connaissent pas Play! (et qui visiblemement ne lisent pas ni le blog d’Ippon, ni le Touilleur Express), il s’agit d’un framework orienté web, full-stack (contient toutes les briques nécessaires pour développer, déjà intégrées et configurées), et qui met l’accent sur la facilité et la rapidité de développement. Il a aussi la particularité de ne rien faire comme les autres… Pour résumer grossièrement, il s’agit d’un équivalent de Ruby on Rails pour le monde Java.

Guillaume Bort, créateur du framework, et Sadek Drobi, un des développeurs principaux, nous ont donc parlé de la prochaine évolution majeure du framework. Ils commencent par faire deux annonces:

  • La sortie de la première bétâ de la future version 2.0.
  • Typesafe (la société créée par Martin Odersky et Jonas Bonér, les créateurs de Scala et d’Akka respectivement), vont intégrer officiellement Play! 2.0 dans leur stack. Une intégration naturelle puisque Play 2.0! s’appuie fortement sur Scala, Akka et sbt… Guillaume Bort en profite également pour intégrer l’Advisory Board de Typesafe, où il sera plutôt en bonne compagnie puisqu’il y rejoint James Gosling et Doug Lea.

Historique

Sadek Drobi, commence par nous rappeler que le framework Play! est né chez Zenexity pour répondre aux besoins de projets réels, avant d’être rendu open source. Il nous fait un rapide rappel de l’évolution du web ces dernières années: d’abord un web statique, composé de simples pages HTML, puis un web dynamique, où on découvre que l’on peut manipuler une page dynamiquement, parfois avec certains excès, ce qui donne lieu à une phase de structuration qui est celle dans laquelle nous nous trouvons actuellement.

Selon Sadek Drobi, la prochaine étape qui nous attends est celle du temps réel, où les informations dans la page seront mises à jour en permanence (pensez Twitter…). Cette évolution du web entraine de nouvelles contraintes : besoin d’une gestion efficace des flux de données, une gestion plus facile de la concurrence, une meilleure élasticité au déploiement… Le but de Play! 2.0 est de répondre à ces nouveaux besoins tout en gardant la philosophie qui le caractérise: prise en main facile et intuitive, full-stack, rapidité de développement…

Nouveautés

Guillaume nous fait ensuite une démo rapide de la console Play! Il s’agit en fait de la console SBT. On peut y lancer des commandes comme compile ou run. SBT est wrappée dans le script “play” ce qui permet d’utiliser les même commandes que pour Play! 1.x (ex: play new, play run, play test…). On peut également lancer l’interpréteur scala depuis la console, et ainsi avoir accès directement aux classes de notre projet, y compris les templates compilées. On peut donc appeler une template à la main et voir tout de suite le HTML généré. Utile pour débogger…

Guillaume nous montre ensuite qu’on peut mélanger Java et Scala dans le même projet, avec le même système de recompilation à la volée, de rechargement à chaud, et d’affichage des erreurs directement dans le navigateur. Il nous présente aussi le nouveau système de templating. Exit Groovy, place à Scala.  L’avantage est que les templates sont compilées comme des fonctions Scala, et bénéficient de tous les avantages du typage fort. Si vous renommez un champ d’un bean, vous saurez dès la compilation que vous avez oublié de mettre à jour un template. Plutôt pratique…

Fin de la démo. Sadek reprend la parole pour nous parler des besoins grandissant d’asynchronicité pour les applications web. Lorsqu’on appelle un système externe pour récupérer des données (appel REST, WS, ou autre…), il n’est plus question de bloquer un thread de traitement des requêtes pendant qu’on attend la réponse. Lorsqu’on veut traiter un gros flux de données, il n’est pas question de tout charger en mémoire pour le traiter ensuite. Il faut mieux maîtriser la consommation des ressources (threads, CPU, mémoire). Il faut sortir des API bloquantes (genre InputStream), et mettre en place une méthode plus efficace que simplement passer un callback à une méthode asynchrone. Sadek nous dit qu’il faut faire du “reactive programming”: réagir à des évènements (une requête arrive, la réponse d’un processus long est arrivée…).

Il introduit ensuite la réponse de Play! à ce problème: le concept d’Iteratee et d’Enumerator. Concept apparement inspiré par le langage Haskell. De ce que j’en ai compris, il s’agit d’une sorte d’un producteur (l’Enumerator) qui notifie un consomateur (l’Iteratee) que de nouvelles données sont disponibles. L’Iteratee peut ensuite répondre de plusieurs façons:

  • Continue: envoie moi encore des données, et traite les de cette façon là.
  • Stop: arrête de m’envoyer des données (et libère potentiellement les resources)
  • Error: tu m’envoies des données invalides.

Play! utilise Akka et le modèle d’acteur pour implémenter ces concepts. Ce point à vraiment l’air d’être une des nouveautés importantes, et je suis curieux de voir un exemple concret de mise en pratique de ce pattern…

Sadek nous parle ensuite de la couche de persistance. Il nous dit qu’il est illusoire pour eux d’essayer de faire une couche d’abstraction générique de la persistance, les technologies sous-jacentes étant trop différentes (bases relationnelles, bases NoSQL, etc…). Ils préfèrent implémenter des API spécifiques grâce à des modules spécifiques. Pour la version Scala, l’implémentation par défaut est Anorm (une simple couche au dessus de JDBC). Pour la version Java, EBeans est utilisé comme implémentation légère de JPA.

Sadek et Guillaume nous parlent ensuite de l’avantage d’utiliser SBT comme outil de build. SBT étant extensible, il est possible d’écrire des modules qui viendront étendre le cycle de vie de l’application. Par exemple, on peut déclarer des “compiled assets”, c’est à dire des resources qui seront compilées automatiquement par Play! en cas de changement, et dont les erreurs seront affichées dans le navigateur, de la même manière que pour les fichiers sources Java ou Scala. On peut par exemple gérer ainsi la compilation des CSS avec Less, ou bien des fichiers Javascript avec CoffeeScript.

Conclusion

En conclusion, la réécriture de Play! leur a apporté un certain nombre d’effets de bords bénéfiques, tels que de meilleures performances, mais aussi d’apporter du “type-safety” partout, y compris dans la couche présentation (les templates), et dans le fichier route (une route définie qui pointe vers une méthode de contrôleur inexistante sera détectée à la compilation).

Un bémol toutefois: il est à noter que Play 2.0 sera incompatible avec Play 1.x, tant au niveau des API que du moteur de templating, et qu’il n’existe pas de stratégie de migration bien définie. Les changements d’API devront être gérés à la main. Pour ce qui est des templates, il faudra soit les réécrire toutes (pas forcément très réaliste), soit espérer que quelqu’un fasse un module pour pouvoir utiliser le moteur de templating basé sur Groovy avec Play! 2.0. Les projets existants sous Play 1.x risquent de ne pas être migrés vers la version 2.0, mais combien de temps la branche 1.x sera-t-elle maintenue ? De même, Play! 2.0 propose une API Java et une API Scala. On peut se demander combien de temps ces deux APIs seront maintenues en parallèle, et si l’API Java ne sera pas dans le futur reléguée au deuxième plan.

Play! est souvent perçu comme le trublion des frameworks web, et génère souvent des réactions assez polarisées (on adore ou on déteste). Mais on ne peut que constater en étant à Devoxx qu’il jouit d’une popularité croissante en voyant le nombre talks lui sont consacrés cette année. Et l’annonce de son intégration à la stack Typesafe, qui offrira un support commercial, en est une preuve supplémentaire.