Accueil > Frameworks > La cuisine avec Vert.x

La cuisine avec Vert.x

Vert.x est un framework web voué à rendre plus accessible la création d’applications asynchrones et scalables grâce à une API simple qui tire le meilleur parti de la JVM. Son développement est soutenu par VMWare.

Vert.x est développé en java, mais il existe une API pour Groovy, Ruby, Javascript et bientôt Scala et Clojure. Il est donc possible de développer une application dans chacun des ces langages, ou même de les mélanger.

Alors, Vert.x tient-il ses promesses ? Voyons cela via une petite série d’articles dans lesquels je montrerai comment

  • développer un webservice REST tout simple
  • ajouter la persistance des données (via MongoDB)
  • utiliser Vert.x coté serveur et coté client

Rassemblez vos ustensiles ! - un petit peu de vocabulaire vert.x

Un projet Vert.x est constitué d’un ou plusieurs verticles. Un verticle est un noeud que l’on peut déployer sur un serveur. Grâce à cela, nous sommes capables de scaler horizontalement notre application en déployant plusieurs verticles au sein d’un réseau de serveur (sur un service PaaS typiquement).

Vert.x se veut modulaire. À l’instar de node.js, vos projets sont exportables sous forme de modules, appellés mods. Ils deviennent alors utilisables par d’autres projets Vert.x. Ces modules peuvent communiquer ensemble via un mécanisme d’eventbus, ils deviennent alors des busmods.

Ce système d’eventbus est central dans la philosophie Vert.x puisqu’en plus de permettre la communication entre les mods, il permet aux différents verticles de dialoguer lorsqu’ils sont répartis. C’est ce qui rend, théoriquement, les projets Vert.x scalables.

Pour commencer (très) simplement, je n’utiliserai vert.x que pour la partie serveur. Le client sera une simple page avec un peu de javascript. Notez cependant que l’on peut étendre l’eventbus jusqu’au client. J’y reviendrai.

 

Une démo chef  ? - Make your own soup (myos)

Je vais créer un petit serveur, dont le rôle est de nous cuisiner une petite soupe avec les ingrédients que l’on veut.
Vous pouvez retrouver le code intégral de l’application sur GitHub (Choisissez bien la branche myos-0.0.1. Il y en a une par article).

 

La communication en cuisine

Le format Json est très bien intégré à Vert.x, qui en fait – selon le manuel – sa lingua franca. En clair, l’API rend la création et la manipulation d’objets Json très simple.

Le client et le serveur dialogueront via les requêtes suivantes :

/availableIngredients.json La liste des ingrédients disponibles dans la cuisine
/recipe.json La recette actuelle
/set/:ingredient/:quantity Fixe la quantité d’un ingrédient à ajouter dans la soupe

 

Notre application suivra le diagramme de séquence suivant :

 

Ce qui donne, en utilisant nos interfaces :

 

 

Le client

J’ai commencé par faire une petite interface qui permet de définir la quantité de chaque ingrédient et affiche la recette de la soupe. Techniquement, j’ai mélangé une pincée de JQueryUI dans un bol de Twitter Bootstrap pour une page fondante et vite réalisée (mon petit secret pour lier la sauce : jquery-ui-bootstrap).

 

 

Le serveur

C’est le moment du plat de résistance.
La structure du projet est simple :

Les ingrédients sont contenus dans un enum capable de renvoyer l’ensemble des ingrédients sous forme d’objet Json.

La recette contenue sur le serveur est représentée par un ensemble d’ingrédients. On peut lui ajouter (ou modifier la quantité) des ingrédients et récupérer la liste sous forme de JsonObject. Simple !

 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Recipe {

    private Map<Ingredient, Integer> ingredients = new HashMap<Ingredient, Integer>();

    public Ingredient setSomeOf(String ingredientString, String quantityString){
        Ingredient ingredient;
        Integer quantity;
        try{
            ingredient = Ingredient.valueOf(ingredientString.toUpperCase());
            quantity = Integer.decode(quantityString);
        }catch(IllegalArgumentException e){
            return null;
        }
        ingredients.put(ingredient, quantity);
        return ingredient;
    }

    public JsonObject getIngredientsAsJson() {
        Map<String, Object> map = new HashMap<String, Object>();
        for(Ingredient ingredient : ingredients.keySet()){
            map.put(ingredient.toString(), ingredients.get(ingredient));
        }
        return new JsonObject(map);
    }

}

 

 

La classe Server est le point d’entrée de l’application, elle étend Verticle et implémente la méthode

public abstract void start() throws java.lang.Exception

C’est cette méthode qui est exécutée au lancement de l’application. C’est donc ici que l’on va définir le comportement du serveur : un serveur HTTP à l’écoute du port 8080.

vertx.createHttpServer().requestHandler(rm).listen(8080);

 

L’API de vert.x nous offre plusieurs Handlers, permettant de traiter les requêtes reçues par le serveur. Pour créer un serveur REST, je m’aiguille naturellement vers RouteMatcher qui me permet de trier les requêtes selon leur pattern :


1
2
3
4
5
6
7
RouteMatcher rm = new RouteMatcher();

rm.get("regex", new Handler<HttpServerRequest>() {
    public void handle(final HttpServerRequest req) {
        req.response.end("Please, can I have some more ?");
    }
});

 

Par exemple, dans la classe Server de myos la requête http://server/set/carrot/4 sera traitée par le handler suivant :


1
2
3
4
5
6
7
8
9
10
11
12
13
RouteMatcher rm = new RouteMatcher();

rm.get("/set/:ingredient/:quantity", new Handler<HttpServerRequest>() {
    public void handle(final HttpServerRequest req) {
        if (recipe.setSomeOf(req.params().get("ingredient"), req.params().get("quantity")) == null) {
            req.response.statusCode = 400;
            req.response.statusMessage = "Can't find that ingredient";
            req.response.end();
        } else {
            req.response.end(recipe.getIngredientsAsJson().encode());
        }
    }
});

Jusque là, rien de très compliqué. On a vu comment créer un serveur HTTP, traiter les requêtes et répondre au client.

Notre petit système montre tout de même rapidement ses limites : tout le monde va se partager la même recette de soupe ! Je ne suis pas contre la cuisine communautaire, mais il faudrait tout de même penser à intégrer une notion de session.
C’est ce que nous feront dans l’article suivant.

Share
Categories: Frameworks Tags:
  1. 05/09/2012 à 10:07 | #1

    Article très prometteur!
    En revanche, les choses bougent vite sur vert.x et, sauf erreur de ma part, les groupId/artifactId ont changé pour org.vert-x/vertx-yyyyyy
    De plus, les sources ne devraient-elles pas être dans src/main/java (plutôt que src/)??

    A noter qu’une bonne option PaaS pour déployer du vert.x est cloudfoundry.com, qui supporte à présent Java7 (un pré-requis pour vert.x) : http://blog.cloudfoundry.com/2012/08/06/deploying-vert-x-applications-to-cloud-foundry/

    Dès que le temps le permet, je compte bien creuser un peu cette appli, la cuisine a l’air vraiment sympa :)

  2. 22/10/2012 à 10:43 | #2

    Tu as raison, les groupId et artifactId devraient être en org.vert-x et vertx-myos. Ça a changé peu de temps après mon dernier commit sur le projet.
    Je devrais reprendre ça pour le mettre à jour.

  1. Pas encore de trackbacks