Premier coding Dojo à Bordeaux

Mardi 24 Septembre, le premier Coding Dojo de Bordeaux a eu lieu. En voici le bilan.

Objectif de la journée

Le coding Dojo bordelais a pour but le développement d’une application web et mobile de consommation locale (circuits courts). Celui-ci s’intègre aux projets de développement durable initiés par le conseil général de Gironde et la CUB (Communauté Urbaine de Bordeaux) : http://www.datalocale.fr/drupal7/blog/concours-derniere-ligne-droite

A partir d’une carte, l’utilisateur pourra visualiser les producteurs effectuant de la vente directe, les marchés ou les magasins vendant des produits locaux, et ceci autour de sa position ou par une recherche localisée ou typée (fruits, légumes, viande, …)

Cette première journée a été orientée sur le choix des technologies qui seront utilisées lors de la réalisation de l’application.

Déroulement du Coding Dojo

Après un petit déjeuner copieux, les binômes ont été formés autour de 5 ateliers :

  • Responsive Design

  • Framework MVC

  • Serveur

  • Base de données

  • Cartographie

Ne vous inquiétez pas, Kevan a fini les viennoiseries restantes juste après cette photo 🙂

Chaque binôme a choisi 2 technos à étudier, qu’ils présenteront en fin de journée afin que l’on choisisse celle des deux qui correspond le mieux au projet final.

Les technologies choisies par les binômes :

  • Responsive Design : Bootstrap et UIKit
  • Framework MVC : Angular JS et Ember.js
  • Serveur : RESTX et RESTify (Node.js)
  • Base de données : MongoDB et Reddis
  • Cartographie : OpenStreetMap avec Leaflet et Angular-leaflet-directive

Responsive design

Le binôme a analysé des technologies reposant sur la conception d’applications web disponibles sur différents appareils (ordinateur, téléphone, tablette, …). Il existe une panoplie de choix de technologies Responsive Design (Grumby, Lnk, Bootstrap, Uikit, …)

Dans un premier temps, une sélection s’est imposée. Les critères de choix étaient les suivants :

  • avoir une documentation complète
  • disponible sur plusieurs appareils
  • compatible avec la majorité des navigateurs (IE 8+, Chrome, Firefox)
  • un panel de composant
  • une technologie non obsolète

Le binôme a retenu : Bootstrap et Uikit.

Bootstrap

Avantages :

  • compatible avec appareil mobile ou autre (tablette, ordinateur) : redimensionnement auto selon l’appareil
  • une bonne documentation
  • un panel de composants : les composants existants suffisent pour  développer l’application
  • possibilité de personnaliser son look-and-feel
  • un écosystème étendu : il existe de nombreux plugins
  • un éditeur en ligne
  • Facile et rapide à mettre en place
  • Compatible avec les navigateurs IE 8+, Chrome, Firefox

Inconvénients :

  • Tous les sites utilisant Bootstrap ont le même style de design

UIkit

Avantages :

  • compatible avec appareil mobile ou autre (tablette, ordinateur): redimensionnement auto selon l’appareil
  • personnaliser son look-and-feel
  • Facile à utiliser

Inconvénients :

  • formulaire peu développé
  • IE: compatible seulement avec IE9+

Le framework Boostrap a été retenu pour sa panoplie de fonctionnalités et ses compatibilités plus larges.

Framework MVC

Il existe actuellement une abondance de Frameworks Javascript. Enfin de restreindre le choix à tester, la sélection a été préalablement effectuée à l’aide du site http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/. Ce dernier effectue un tour d’horizon rapide des frameworks les plus courants et les compare suivant certaines fonctionnalités (UI Bindings, Composed Views, Web presentation layer, plays nicely with others).

Les caractéristiques primordiales étant la facilité d’intégration avec d’autres Frameworks JS et surtout une prise en main rapide. Le binôme a ainsi retenu  : Ember.js et Angular.js.

Le but du codingDojo était de réaliser simplement et rapidement une single page affichant :

  • un tableau de producteurs (depuis une liste JSON)
  • un champ de recherche/tri
  • le détail du producteur à partir d’un lien affiché dans le tableau

Ember.js

Avantages :

  • le plus complet
  • UI Bindings : directionnel entre la vue et le modèle
  • Composed Views
  • Web Presentation Layer
  • Respecte le pattern MVC
  • Se charge de la communication avec le serveur (routes)
  • Moteur de template Handlebar (plus complet que Moustache)
  • Documentation complète

Inconvénients :

  • Semble être destiné à des projets importants
  • Délicat à prendre en main pour devs non JS

Angular.js

Avantages :

  • Bonne documentation
  • UI Bindings : bi-directionnel entre la vue et le modèle
  • Composed Views
  • Template déclaratifs en HTML
  • Respecte le pattern MVC
  • Très léger et facile à prendre en main

Inconvénients :

  • Framework reservé à la partie UI (nécessite de le coupler à d’autres choses pour les besoins plus étendus)
  • Ne contient pas de composants “out-of-box”

Ayant développé le POC voulu en un temps assez court avec Angular.js, le binome a pu regarder les frameworks Knockout et Batman.js

Knockout.js

Avantages :

  • Très bonne gestion des événements
  • Template déclaratifs en HTML
  • Relativement simple à mettre en place

Inconvénients :

  • Plus complexe qu’AngularJS
  • Assez intrusif dans le code HTML

Batman.js

Avantages :

  • Bien pour les developpeurs rails -> orienté CoffeeScript
  • Orienté MVC

Inconvénients :

  • Bien pour les developpeurs rails -> orienté CoffeeScript
  • Documentation incomplète et peu abondante

Le framework AngularJS a été retenu pour sa simplicité d’utilisation et de prise en main. Pour le besoin très simple de notre site, il sera parfait et ne sera pas time-consuming en apprentissage.

Base de données

Le binôme a analysé deux types de bases de données NoSQL réputées pour leurs performances : MongoDB qui est une base de donnée orientée “Documents” et Redis, qui est orientée “clé-valeur”.

Bases NoSQL

Redis

Avantages :

  • Bonnes performances pour les actions (lecture/ecriture) sur les données. Celles-ci sont dues à la méthode de stockage des données, qui se font entièrement dans la mémoire vive
  • Installation rapide de la base de données
  • Possède une interface en ligne de commande pour effectuer des requêtes sur les bases

Inconvénients :

  • La base de donnée ne renvoie qu’une collection de l’ensemble des données en lecture. On ne peut donc pas effectuer de requêtes “avancées” pour rechercher par exemple les producteurs qui sont situés à Libourne.

MongoDB

Avantages :

  • Bonnes performances pour les actions (lecture/ecriture) sur les données.
  • L’installation de la base de donnée est rapide est sans difficultés
  • Possède une interface en ligne de commande pour effectuer des requêtes sur les bases
  • Meilleure visibilité des données

Inconvénients :

  • L’orientation “Document” des données n’est pas facile à adopter

Couche d’accès aux données

Nous avons choisi de simplifier et unifier l’accès à la couche de données en utilisant la surcouche d’abstraction Spring Data, à travers ses modules spécialisés pour chaque base de données.

org.springframework.data spring-data-redis 1.1.0.RELEASE org.springframework.data spring-data-mongodb 1.3.1.RELEASE

Ceci nous permet de comparer les API des deux bases de données avec des DAOs spécialisés par BDD.

Voici l’interface de notre DAO :

public interface GenericMarcheDAO {
void putMarche(Marche marche);
void delete(String key);
Marche get(String key);
List getObjects();
public List getProducteurDansVille(String value);
}

Examinons la méthode permettant de sauvegarder un marché :

Pour Redis :

public void putMarche(Marche marche) {
redisTemplate.opsForHash().put(marche.getObjectKey(),marche.getKey(),marche);
}

Pour MongoDB :

public void putMarche(Marche marche) {
mongoTemplate.save(marche);
}

Nous voyons que la méthode de MongoDB est plus intuitive et ressemble à une utilisation de Hibernate alors que la syntaxe Redis est un peu plus spécifique (orientée clé/valeur).

Nous avons eu du mal à faire fonctionner le connecteur MongoDB car nous avions pris la mauvaise classe en cherchant à faire fonctionner notre DAO avec MongoRepository alors qu’il fallait simplement utiliser MongoTemplate.

Nous n’avons pas pu effectuer la recherche des producteurs de Libourne sur notre DAO Redis, nous montrons donc uniquement comment accéder à l’API de recherche de MongoDB:

public List getProducteurDansVille(String value) {
Query query = new Query(Criteria.where(“ville”).is(value));
return mongoTemplate.find(query,Marche.class);
}

Le choix final de l’équipe s’est finalement porté sur MongoDB pour deux raisons principales :

  • Les tests de performance ont révélé que même avec une requête de recherche supplémentaire (“Producteurs situés sur Libourne”), MongoDB reste plus performant que Redis (moins de 20 secondes pour MongoDB pour insérer 10 000 données et exécuter deux requêtes de recherche, 27 secondes pour Redis pour l’insertion de 10 000 données et exécuter une requête de recherche)
  • De plus, pour les besoins de l’application, MongoDB est plus avantageux avec la possibilité d’exécuter des requêtes plus spécifiques et avancées.

Serveur

Le binôme a été chargé de développer la partie web services RESTful. Afin de réaliser cette partie, deux technologies ont été étudiées :

  • RESTX, développé en Java
  • Restify, basé sur Node.js (JavaScript).

Ces deux technologies s’appuient sur une base de données MongoDB.

RESTX est un Framework Open Source Java.

Avantages :

  • Léger et très rapide
  • API testable, grâce aux scénarios détaillés « Spec Concept »
  • Génération de code depuis le shell intégré
  • Génération automatique de la documentation de l’API (« endpoints »)
  • Console d’administration web
  • Support de multiples gestionnaires de dépendances (Maven, Ivy)
  • Intégration avec MongoDB grâce à Jongo
  • Embarque des librairies populaires (Guava, JodaTime)

Inconvénients :

  • Pas de support des expressions régulières pour les routes
  • Pas de support des sockets
  • Actuellement en développement

Restify est un module de Node.js qui permet de concevoir des web services REST aisément. Ce module, basé sur Express, Framework web de référence pour Node.js, propose donc des performances de premier plan.

Avantages :

  • JavaScript : JSON natif, pas de compilation
  • Flexibilité de Node.js (NPM)
  • Driver MongoDB natif
  • Support de Socket.io
  • Routes versionnées (permet de maintenir plusieurs versions d’une API)
  • Nombreux plugins fournis (JSONP, Query String, …)

Inconvénients :

  • Implémentation du serveur à la charge du développeur
  • Ne propose pas de support pour les tests unitaires

La technologie RESTify a été retenue car les webservices ne sont pas nombreux ni compliqués (recherche par critères, insertion d’un nouveau POI). Ils ne nécessiteront donc pas de tests unitaires compliqués. De plus, cette solution nous affranchit de la déserialisation de JSON vers Java pour être re-serialisé de Java vers JSON. En effet, MongoDB va nous renvoyer du JSON, et c’est du JSON qui est attendu par le Front (notamment OpenStreetMap pour afficher les markers).

Cartographie

Google Map étant payant à forte volumétrie, nous nous sommes naturellement orientés vers OpenStreetMap.

Le binôme a étudié tout d’abord Leaflet, couche graphique utilisant la base OpenStreetMap pour créer des cartes, pour voir ses possibilités. Ensuite, voyant que Angular JS était bien positionné, nous avons étudié le Angular-leaflet-directive disponible sur github.

Le plus compliqué avec OpenStreetMap est de choisir la carte. En effet, l’API OSM ne fournit pas les layers, juste la base de données des coordonnées d’objets et les services d’ajout de POI.

Ce qui est amusant dans les cartes disponibles, c’est que chaque carte est très spécialisée. On peut trouver des cartes mettant en avant des chemins de VTT, des canaux fluviaux, des montagnes, …

La première carte “jolie” que nous avions trouvée était en fait une carte des canaux fluviaux, et donc en zoom minimal, cela faisait vraiment bizarre :

Après avoir trouvé une carte plus générique, nous avons commencé à faire notre POC Leaflet.

Leaflet est en fait très simple à utiliser. Il suffit de créer la map :

var map = L.map(‘map’, {
center: [44.841909,-0.578778], //centrée sur Bordeaux bien sûr !
zoom: 14 //un petit zoom décent
});

puis de lui affecter le “joli” layer :

L.tileLayer(‘http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpg’,
{attribution: ‘Map data & copy; OpenStreetMap contributors’, //le petit copyright en bas à droite de la map
maxZoom: 18, //divers options comme minZoom, maxZoom, …
subdomains: “1234” //chargement des images sur 4 mirroirs
}).addTo(map);

La carte est maintenant opérationnelle, on peut lui ajouter des markers :

var marker = new L.marker([obj.lat, obj.lng]).bindPopup(popupContent).addToMap(map);

ou plutôt ajouter des markers à un LayerGroup qui permettra de retirer tous les markers d’une recherche d’un coup :

var markers = new L.LayerGroup().addTo(map);
markers.addLayer(marker);
markers.clearLayers();

Puisque le choix du Framework MVC a été fait sur Angular JS, nous avons aussi regardé le Leaflet directive for AngularJS. Cette directive relie Angular et Leaflet, permettant d’utiliser Leaflet au travers de code Angular et ainsi simplifier le code JS.

La directive est toutefois très peu documentée, et seuls des exemples permettent de comprendre le fonctionnement. On peut vite se retrouver bloqué sur une fonctionnalité, et devoir aller voir le code source de la directive pour connaître les options disponibles.

Exemple :

Relier les champs Angular pour centrer la carte :

Latitude : Longitude : Zoom :

La directive permet de drag’n drop des markers, tracer des chemins entre des markers, ajouter des markers, des legends, catcher les événéments de la map (zoom, déplacements, …) , …

Application finale

L’application finale sera en :

  • Bootstrap
  • Angular JS
  • Yeoman
  • RESTify (Node.js)
  • MongoDB
  • OpenStreetMap, Angular-Leaflet-Directive

Photos du Coding Dojo : http://photos.ippon.fr/Ippon/CodingDojo-Bordeaux

POC du Coding Dojo : https://github.com/mleneveut/IpponCodingDojoBordeaux