Accueil > Frameworks > Marions les saveurs – Vert.x avec MongoDB

Marions les saveurs – Vert.x avec MongoDB

Après avoir présenté brièvement les concepts de Vert.x et un cas simple d’utilisation, étoffons un peu notre application.
Pour rappel, Myos-0.0.1 permettait de décrire les ingrédients d’une soupe et d’en recevoir la recette sous forme de Json. Un problème se pose : tous les utilisateurs partagent la même recette.

Pour que chacun puisse créer sa recette, je vous propose de fabriquer un système basique de session, basé sur les cookies. Les données seront enregistrées dans une base MongoDB. Tout ceci sera inclut dans Myos-0.1.1.

Persister les données en session

Comme décrit dans la doc de mongoDB, on peut facilement implémenter un système de session en enregistrant les objets dans une base MongoDB.

En effet, MongoDB attribut à chaque document persisté un identifiant unique nommé “_id”. Si l’on précise cet identifiant lorsque l’on enregistre un document, Mongo va retrouver la version persistée et la mettre à jour.

C’est donc cette clé primaire “_id” que l’on stockera coté client, dans un cookie.

Pour résumer ce fonctionnement, voici le comportement type que devra avoir Myos-0.1.1 lors de l’enregistrement d’un nouveau client :

Le Busmod MongoDB Persistor

Vert.x est livré avec un Busmod appellé MongoDB Persistor. Ce mod propose d’accèder facilement à une base de donnée MongoDB. Comme je l’ai évoqué dans l’article précédent, les Busmods communiquent via l’eventbus de Vert.x.

On le lance programatiquement via :
 this.container.deployWorkerVerticle("mongo-persistor", mongoConf);
où mongoConf est un Json contenant les informations de connexion à la base.

Il suffit alors d’envoyer les requêtes Mongo sous forme de Json sur l’eventbus, à l’attention du busmod :
 eventBus.send("vertx.mongopersistor", jsonQuery, callback);
où callback, comme son nom l’indique, est la méthode executée à la fin du traitement.

Les requêtes sont passées en Json. Par exemple, si on écrit dans le Shell Mongo :

db.myos.save({"Fenouil": 4, "Radis": 8});


on passera le Json suivant à Mongo persistor :


1
2
3
4
5
{
"action": "save",
"collection": "myos",
"document": { "Fenouil": 4, "Radis": 8 }
}

La gestion des cookies

Un cookie, ce n’est rien d’autre qu’un header. On le gère donc très facilement :


1
2
3
4
5
6
rm.get("/whatsMyCookie", new Handler<HttpServerRequest>() {
    public void handle(HttpServerRequest req) {
        String cookie = req.headers().get("Cookie"); //La valeur contenue dans cookie
        req.response.end(cookie);
    }
});

1
2
3
4
5
rm.get("/setMyCookie", new Handler<HttpServerRequest>() {
    public void handle(HttpServerRequest req) {
        req.response.headers().put("Set-Cookie", "sessionid=blabla;Path=/; Domain=localhost");
    }
});

 

En pratique, dans Myos

En pratique, ce n’est pas beaucoup plus compliqué. Je vais reprendre notre application telle qu’on l’a laissée dans l’article précédent et la modifier un peu.

La classe Recipe, qui contenait la recette devient un accesseur à la base de donnée, je la renomme donc en RecipeDao. C’est à travers cette entitée que notre Server dialoguera avec la base. Pour plus de lisibilité, je crée deux Helpers : MongoDbHelper et CookieHelper qui aiderons RecipeDao et Server dans leur tâche.

Grâce à cela, la partie utile de Server devient :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
rm.get("/set/:ingredient/:quantity", new Handler<HttpServerRequest>() {
    public void handle(final HttpServerRequest req) {
        String sessionid = CookieHelper.getSessionid(req.headers());
        RecipeDao.setSomeOf(req.params().get("ingredient"), req.params().get("quantity"), sessionid, req, eventBus);
    }
});
rm.get("/recipe.json", new Handler<HttpServerRequest>() {
    public void handle(HttpServerRequest req) {
        String sessionid = CookieHelper.getSessionid(req.headers());
        RecipeDao.getIngredientsAsJson(sessionid, req, eventBus);
    }
});
rm.get("/availableIngredients.json", new Handler<HttpServerRequest>() {
    public void handle(HttpServerRequest req) {
        String sessionid = CookieHelper.getSessionid(req.headers());
        RecipeDao.getAvailableIngredientsAsJson(sessionid, req, eventBus);
    }
});

Je vous laisse regarder les helpers pour voir ce qu’il se passe sous le capot !

Je retiens deux grandes notions de Vert.x :

  • Le bus, qui permet de réduire le couplage entre les modules.
  • Les busmods réutilisables, qui se voient chacun attribuer une responsabilité.

Nous utilisons ici un busmod fournit par le framework, il faut aussi penser l’architecture de nos applications sous cette forme, déclarer nos propres modules et les réutiliser.

Par contre, comme prévu, Java est un peu verbeux dès qu’il s’agit de gestion asynchrone (et donc de callbacks). D’autres langages seraient surement plus adaptés (Javascript ? Groovy ? Scala quand il sera pris en charge !), profitons du multilinguisme de Vert.x.

Share
Categories: Frameworks Tags: ,
  1. Pas encore de commentaire
  1. Pas encore de trackbacks