Golo et interopérabilité Java par l’exemple avec Jetty, SparkJava et Vert.x
J’adore dire que Golo est de la “sucrette syntaxique” pour Java. Ce que je veux dire par là c’est que Golo permet non seulement de rendre Java “plus simple” mais aussi “d’interopérer” facilement avec Java. C’était le cas depuis le début, mais depuis quelques semaines Golo a connu quelques évolutions notables sur le sujet.
Au début : les Single Method Interfaces
Golo sait bien sûr instancier toute sorte d’objets(classes) Java, de l’API Java ou en provenance de librairies(frameworks) Java existants, comme par exemple utiliser com.sun.net.httpserver.HttpServer pour faire un mini serveur http :
Mais ensuite si on veut faire bosser notre serveur, nous avons besoin de passer un objet qui implémente l’interfaceHttpHandler à la méthode createContext() de server, en Java nous aurions ceci :
Du coup pour avoir notre instance de handler implémentant HttpHandler il nous suffira d’écrire : let handler = |fct| -> fct: to(HttpHandler.class)et notre mini serveur http resemblera à ceci :
Je veux faire pareil avec Jetty ! Vive l’AdapterFabric
La problématique dans le cas de Jetty, c’est que le serveur (org.eclipse.jetty.server.Server) a une méthode setHandler() qui “attend” un objet de type org.eclipse.jetty.server.handler.AbstractHandler (donc héritage) qui lui même implémente l’interface Handler (http://download.eclipse.org/jetty/stable-7/apidocs/org/eclipse/jetty/server/Handler.html), donc il va falloir en plus lui écrire une méthode handle().
Je le répète : le concept de classe n’existe pas en Golo, mais depuis peu nous avons l’AdapterFabric qui permet de créer des “espèces” de proxies dynamiques mais en poussant le concept un peu plus loin puis que l’on peu créer des objets dynamiques pouvant hériter de classe java, pouvant implémenter des interfaces java tout en définissant les méthodes à implémenter voire même en surchargeant les méthodes héritées.
Donc dans le cas de Jetty, il faudra définir une “configuration” pour “représenter” AbstractHandler :
Puis pour instancier notre AbstractHandler il nous suffira d’écrire ceci :
Et enfin notre serveur à base de Jetty ressemblera donc à ceci :
Ça marche aussi pour les copains et vive les DSL web !
Cette nouvelle capacité de Golo (l’AdapterFabric) alliée à sa capacité à créer des DSL va nous permettre d’écrire par exemple des DSL REST “à la Node.js” à partir de frameworks Java existants, tels Spark Java (mon petit préféré) ou même Vert.x. Voici donc des exemples (qui fonctionnent) pour ces 2 frameworks :
SparkJava :
Dans le cas de Spark ce qui nous intéresse, c’est le concept de Route dont nous définirons la configuration (ci-dessous) pour avoir un objet qui hérite “dynamiquement” de spark.Route" et qui implémente handle() :
Remarque : Spark fonctionne sur une base Jetty d’où la similarité avec l’exemple précédent.
Et voici notre serveur (avec le DSL dans le corps de main)
Vert.x
Et un petit dernier pour la route : la version avec Vert.x en mode “embedded” qui globalement suit une logique très proche, sauf que cette fois ci nous ne créons pas un objet qui “hérite” de quelque chose mais un objet qui “implémente dynamiquement” une interface org.vertx.java.core.Handler, donc dans ce cas là la configuration sera la suivante :
Et voici donc notre serveur :
Conclusion
C’était certes rapide, mais vous avez pu voir qu’il était extrêmement facile de se plugger à des frameworks existants et d’en simplifier l’utilisation.