Vert-X + Groovy: un excellent combo pour le web
Ces derniĂšres annĂ©es, ma vie de dĂ©veloppeur a Ă©tĂ© trĂšs largement influencĂ©e par PlayFramework 1 (en Java) puis par Express (Node, donc du JavaScript) aprĂšs avoir compris que Play 2 nâĂ©tait pas pour moi (disparition de la magie). Cependant, mĂȘme si Node câest trĂšs bien et que cela rĂ©pond Ă 80% des besoins, pour les 20% restant jâen reviens Ă Java ⊠Mais avec une petite perte de souplesse ⊠Jusquâau jour oĂč jâai dĂ©cidĂ© de redonner une chance Ă Vert-X (un projet modulaire pour faire des webapps ârĂ©activesâ). Je regardais ce projet rĂ©guliĂšrement, mais Ă chaque fois que je creusais, au bout dâun moment je âbloquaisâ sur tel ou tel point et je passais Ă autre chose parce que je ne trouvais pas de solution.
Le renforcement rĂ©cent de lâĂ©quipe Vert-X (je pense Ă @julienviet et @clementplop, et ceux que je ne connais pas) a contribuĂ© Ă lâapparition de plus de âsamplesâ, plus de documentation âhumainement lisibleâ, âŠ
Donc, aujourdâhui, nous allons voir comment rapidement crĂ©er un projet web avec Vert-X, Maven et Groovy. Et au fur et Ă mesure de mes dĂ©couvertes je rajouterais un article.
Pourquoi Groovy?: parce quâĂ lâusage, je le trouve bien plus agrĂ©able Ă coder et Ă lire que Java, et que quelques fonctionnalitĂ©s comme lâaugmentation des classes et les traits sont bien pratiques.
Mais aprĂšs cette trop longue introduction, passons Ă lâaction.
Je vous engage quand mĂȘme Ă parcourir la documentation http://vertx.io/docs/
Création du projet
Créez une structure de projet Maven:
my-app/
âââ src/
| âââ main/
| âââ groovy/
| âââ Starter.groovy
âââ pom.xml
Contenu de pom.xml
Je me suis entiÚrement inspiré de ce projet https://github.com/vert-x3/vertx-examples/tree/master/maven-verticles/maven-verticle-groovy-compiled
Ce qui est important, câest cette ligne <main.verticle>groovy:Starter</main.verticle>
. Elle permettra de lancer le code de Starter.groovy
lorsque vous lancerez votre jar (java -jar target/mywebapp-1.0-SNAPSHOT-fat.jar
).
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.typeunsafe</groupId>
<artifactId>mywebapp</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<main.verticle>groovy:Starter</main.verticle>
</properties>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-lang-groovy</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>2.9.1-01</version>
<extensions>true</extensions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<compilerId>groovy-eclipse-compiler</compilerId>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>2.9.1-01</version>
</dependency>
<!-- for 2.8.0-01 and later you must have an explicit dependency on groovy-eclipse-batch -->
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>2.3.7-01</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>io.vertx.core.Launcher</Main-Class>
<Main-Verticle>${main.verticle}</Main-Verticle>
</manifestEntries>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/io.vertx.core.spi.VerticleFactory</resource>
</transformer>
</transformers>
<artifactSet>
</artifactSet>
<outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Contenu de Starter.groovy
Aujourdâhui je veux faire simple. Il me faut:
- un service qui me renvoie de lâhtml (requĂȘte de type
GET
) - un service auquel je puisse passer un paramĂštre et qui me renvoie du json (requĂȘte de type
GET
) - pouvoir servir des pages statiques
Initialisation du server http et du router
import groovy.json.JsonOutput // nous en aurons besoin plus loin
import io.vertx.groovy.ext.web.Router
import io.vertx.groovy.ext.web.handler.StaticHandler
def server = vertx.createHttpServer()
def router = Router.router(vertx)
// mon code viendra ici ...
server.requestHandler(router.&accept).listen(8080)
Vous le voyez, rien de plus simple. Maintenant, ajoutons un service
Notre 1er service
Créons notre premiÚre route:
import groovy.json.JsonOutput
import io.vertx.groovy.ext.web.Router
import io.vertx.groovy.ext.web.handler.StaticHandler
def server = vertx.createHttpServer()
def router = Router.router(vertx)
router.get("/api/yo").handler({ context ->
context.response().putHeader("content-type", "text/html").end("<h1>YO!</h1>")
})
server.requestHandler(router.&accept).listen(8080)
- Maintenant, il vous suffit de âbuilderâ votre projet:
mvn package
- Puis de lancer la commande:
java -jar target/mywebapp-1.0-SNAPSHOT-fat.jar
- Et enfin dâappeler http://localhost:8080/api/yo
Simple!
Service Json
Ajoutons une nouvelle route:
import groovy.json.JsonOutput
import io.vertx.groovy.ext.web.Router
import io.vertx.groovy.ext.web.handler.StaticHandler
def server = vertx.createHttpServer()
def router = Router.router(vertx)
router.get("/api/yo").handler({ context ->
context.response().putHeader("content-type", "text/html").end("<h1>YO!</h1>")
})
// notre nouvelle route pour un service json
router.get("/api/hi/:name").handler({ context ->
String name = context.request().getParam("name").toString()
context
.response()
.putHeader("content-type", "application/json")
.end(JsonOutput.toJson([
"message":"Hi!",
"name": name
]))
})
server.requestHandler(router.&accept).listen(8080)
Donc si jâappelle: http://localhost:8080/api/hi/bob, la variable name
prendra la valeur bob
et mon service me retournera une chaĂźne json comme celle-ci:
{
"message":"Hi!",
"name":"bob"
}
- Donc, vous devez âbuilderâ Ă nouveau votre projet:
mvn package
- Puis de re-lancer la commande:
java -jar target/mywebapp-1.0-SNAPSHOT-fat.jar
- Et enfin appeler http://localhost:8080/api/hi/bob
Toujours simple!
Servir du contenu statique
Pour cela, il vous suffit dâajouter comme derniĂšre route, ceci:
router.route("/*").handler(StaticHandler.create())
Et de créer un répertoire webroot
Ă la racine de votre projet, dans lequel vous pourrez dĂ©poser vos pages statiques, JavaScript, etc âŠ
Un dernier pour la route âŠ
Ce que jâaimais beaucoup dans Play, câĂ©tait ça capacitĂ© Ă rebuilder et recharger lâapplication Ă chaque modification de code. Sachez que câest possible avec Vert-X.
Voici comment faire:
Tout dâabord, crĂ©ez un fichier de script build.sh
avec le contenu suivant:
# !/usr/bin/env bash
mvn package
Rendez le exécutable (chmod a+x build.sh
)
Ensuite créez un nouveau fichier de script go.sh
(lui aussi exécutable chmod a+x go.sh
) avec le contenu suivant:
# !/usr/bin/env bash
./build.sh
java -jar target/atta-1.0-SNAPSHOT-fat.jar --redeploy="**/*.groovy" --onRedeploy="./build.sh"
Vous lancez go.sh
, une premiÚre fois il va builder le projet et ensuite à chaque modification de code groovy, vert-x relancera un build et une exécution.
PlutĂŽt pratique.
VoilĂ . Câest tout pour aujourdâhui, la suite bientĂŽt.
Remerciements
Un grand merci Ă @clementplop pour ses explications et sa patience ;)
Tweet