Archives du blog

Angular, Express et Socket.io

Vous savez, si vous lisez le blog de Ninja Squad régulièrement, que nous donnons des cours dans différents établissements, de la fac aux écoles d’ingé, en passant par l’IUT. Avec cette nouvelle année scolaire, nous voici repartis!

Je donne depuis quelques années un cours sur les web services à l’INSA, à l’invitation du Docteur Ponge : c’est l’occasion de parler SOAP (beurk), REST (yay!) et Websocket (re-yay!).

Cette année, je veux faire une démo des websockets pour que cela soit un peu moins mystérieux. Faire un peu de code live est toujours un exercice périlleux, mais c’est un bon moyen pour échanger avec les étudiants et leur présenter un certain nombre de technologies, qu’ils connaissent parfois de nom ou pas du tout.

Les websockets sont l’occasion idéale de faire une application web basique, mais permettant d’introduire quelques concepts du Web parfois mal connus (HTML, CSS, Javascript) et un peu de code plus innovant (Node.js, Express, Socket.io, AngularJS, Bootstrap), de discuter sur l’histoire du Web, le fonctionnement des navigateurs (Chrome, Firefox, V8…) et quelques outils pratiques (npm, Git). Bref, d’apporter un peu de culture générale de notre métier, chose que j’appréciais beaucoup lors des interventions de professionnels lorsque j’étais étudiant.

Après cette remise en contexte, passons aux choses sérieuses!

Il me fallait donc un exemple d’application, qui me prenne une trentaine de minutes à réaliser au maximum. J’ai choisi de faire simple : une application de vote qui permet de choisir votre framework Javascript préféré, et de voir les résultats en temps réel. Nous allons voir les différentes étapes pour y parvenir.

Vous trouverez le nécessaire pour utiliser l’application sur le repo Github de Ninja Squad.

Express/Angular

La première branche Git, nommée `express` met en place une application Node.js/Express minimale.

    var express = require('express')
      , app = express()
      , server = require('http').createServer(app);
    
    app.use(express.static(__dirname + '/'));
    
    server.listen(9003);

L’application Node.js va servir les ressources statiques sur le port 9003. On peut alors ajouter le fichier HTML de notre application, qui contient basiquement :

    <div class="row">
      <div class="col-xs-4 vote"> {{ vote.choice }} </div>
      <div class="col-xs-4 vote"> {{ vote.votes }} </div> 
      <div class="btn btn-primary col-xs-4">+1</div>
    </div>

Pour chaque vote de la collection `votes`, le choix (VanillaJS, AngularJS, BackboneJS ou EmberJS), le nombre de vote pour ce choix et un bouton pour ajouter un vote seront affichés. Cela est réalisé en utilisant la directive `ng-repeat` d’Angular.

Le bouton de vote comporte l’attribut `ng-click` qui permet de lui lier une fonction à exécuter. Cette fonction `voteFor` est définie dans le controller :

	function VoteCtrl($scope){
      $scope.votes = [ { choice: 1, label: 'VanillaJS', votes: 0 }, { choice: 2, label: 'AngularJS', votes: 0 }, { choice: 3, label: 'BackboneJS', votes: 0 }, { choice: 4, label: 'EmberJS', votes: 0 }];

      $scope.voteFor = function(choice){ $scope.votes[choice-1].votes++; }
    }

Le controller Angular initialise les votes et définit la fonction de vote, qui ajoute simplement 1 aux votes du choix cliqué.

Etape 1 terminée! Passons maintenant à l’intégration de Socket.io.

Socket.io

Socket.io est l’une des librairies les plus utilisées pour les websockets dans Node (même si elle est maintenant concurrencée par d’autres comme SockJS). Elle a l’avantage de gérer le fallback si les websockets ne sont pas disponibles, et d’être très simple à utiliser à la fois côté client et côté serveur.

La branche `websocket` contient le code correspondant. Outre l’installation de socket.io (`npm install` is your best friend), il nous faut modifier un peu le serveur :

    io.sockets.on('connection', function (socket) {
      socket.emit('votes', { votes: votes });
      socket.on('vote', function(msg){
      	votes[msg.vote-1].votes++;
      	io.sockets.emit('votes', { votes: votes });
      })
    });

L’implémentation est naïve mais suffit à la démonstration : à la connexion d’un nouveau client (`socket.on(‘connection’, …)`), on envoie les votes dans l’état du moment (`socket.emit`). Puis, lorsque l’on recevra un vote (`socket.on(‘vote’, …)`), on incrémente les votes du choix correspondant et on informe tous les participants avec les nouvelles valeurs (`io.sockets.emit`).

Reste à mettre à jour le client pour communiquer avec les sockets :

    var socket = io.connect('http://localhost:9003');

    $scope.voteFor = function(choice){
      socket.emit('vote', {vote : choice })
    }

    socket.on('votes', function(msg){
      $scope.votes = msg.votes;
      $scope.$apply();
    });

On commence par se connecter aux websockets (`io.connect`). La fonction `voteFor` est modifiée pour maintenant envoyer un évenement de vote au serveur (`socket.emit`). Enfin, à chaque fois que les votes sont reçus, les votes du `$scope` Angular sont mis à jour. Petite subtilité : comme cette mise à jour intervient en dehors de la boucle d’exécution d’Angular, il nous faut appeler la fonction `$apply()` pour que le framework prenne les nouvelles valeurs en compte et rafraîchisse les vues.

Nous sommes prêts : si vous ouvrez cette application dans deux onglets, vous pourrez la voir se mettre à jour en temps réel!

A noter que le brillant Brian Ford de l’équipe Angular propose un service Angular pour Socket.io, afin de simplifier son utilisation et notamment les appels à `$apply()`.

Vous pouvez voir une démo en ligne, déployé sur Heroku (le code nécessaire pour cette partie est également sur le repo Github).

Espérons que ce petit essai vous plaise et plaise à nos étudiants!

JUGSummerCamp 2012

Premier voyage de l’équipe NinjaSquad, direction La Rochelle pour le JUG Summer Camp. Du Java, du Web, l’océan, une conf gratuite d’une journée avec une organisation irréprochable, il faudrait être difficile pour ne pas aimer!

JUG Summer Camp 2012

Keynote : Nicolas de Loof - @ndeloof

Nicolas nous a fait un numéro de stand up très drôle en parodiant le podcast bien connu dans le monde Java : les Castcodeurs. Comme aucun d’entre eux n’étaient présents, Nicolas a eu l’idée de faire un puppet show en reprenant les traits caractéristiques de chacun d’entre eux, pour faire une keynote originale sur notre métier. Franc succès dans la salle (évidemment seulement drôle si on écoute ce podcast).

La journée se déroule ensuite sur deux tracks de confèrence, il faut donc faire des choix.

Google TV : Olivier Gonthier - @rolios

Première présentation sur la Google TV, petit boîtier qui permet de faire tourner des applis Android sur votre télé, mais pas encore disponible en France (on ne connait même pas les partenariats avec les opérateurs). Le principe est simple : une prise HDMI en entrée reçoit le flux vidéo et une prise HDMI de sortie le renvoie vers la TV. A noter que le code de Google TV n’est pas open source. Sinon techniquement c’est le même market que les applis Android traditionnelles.

Commençons par le point qui fâche et qui, à mon sens, fait perdre tout l’intérêt de la chose : il n’est pas possible de récupérer le flux video, ni la chaine visionnée par l’utilisateur, donc vous pouvez oublier toutes les idées d’applications contextuelles: IMDB sur le film en cours ou les stats du match que vous êtes en train de regarder, c’est foutu!

Mais il y a deux ou trois trucs intéressants quand même : par exemple, le "second screen app", qui permet aux devices Android de s’interfacer avec la GoogleTV et de vous servir de télécommande ou mieux, d’écran annexe pour certaines applications. L’exemple que je trouve assez cool : un jeu de poker Hold’em où la TV affiche la table de jeu (avec les cartes communes et les mises) et chaque joueur voit ses cartes sur son téléphone. Ce genre d’application peut avoir un grand potentiel, je suis sûr que l’on va voir apparaître des applications géniales!

Le développement est de la programmation Android traditionnelle, le SDK étant complété avec des fonctions pures TV (touches telecommande par ex). Si vous souhaitez développer une application Android utilisant le "second screen", vous pouvez utiliser Anymote library (voir dans les exemples de code fournis par Google, dans l’application Blackjack TV).

Il est également possible de développer des applications en html5, la GoogleTV ayant un très bon navigateur Chrome intégré (très bien documenté d’après le speaker). Il est aussi possible de packager votre application avec Phonegap pour la distribuer directement sur le Market.

En plus j’ai gagné la GoogleTV du concours, yay!

Node.js : Romain Maton - @rmat0n

Romain faisait une présentation générale de Node.js (voir articles précédents et les excellents articles de Romain) avec quelques rappels sur les principes de base. C’était une présentation très orientée web-app avec le framework web Express et son moteur de template par défaut Jade (cf article précédent également).

Puis les modules importants :

- l’incontournable Socket.io pour faire des websockets

- logging avec Winston

- nodemon, redémarrage automatique dès que vous modifiez un fichier.

- forever pour relancer l’application en cas d’erreur qui coupe l’appli

- jasmine, qunit pour les tests

Et pour terminer une petite démo sympa avec la librairie speak qui fait parler le navigateur pour annoncer le prochain bus qui passe.

Start me up : Nicolas de Loof - @ndeloof

Après le buffet repas le plus incroyable pour une conf que j’aie vu (les membres de l’orga Mix-it présents étaient impressionnés), on reprend avec ‘Start me up’ ou comment passer rapidement de l’idée à la réalisation (en utilisant Cloudbees, dont Nicolas est employé). L’idée est ici de faire un mini moteur de recherche sur les talks de la conf. Nicolas utilise au passage un autre service dans le cloud que je ne connaissais pas : WebSolr, un Solr as a Service. Cloudbees on aime bien, Mix-it est hébergé gracieusement dessus et ça marche très bien (le support a toujours été très réactif en cas de problème).

La présentation est intéressante, Nicolas étant un bon speaker, mais si vous avez déjà vu une présentation de Cloudbees le contenu ne vous surprendra pas (comment déployer, comment gérer ses instances, comment déclarer des propriétés pour le déploiement etc.). La nouveauté la plus notable est sans doute le Click Start, qui permet en un clic de créer tout ce qui va bien pour un type d’application (squelette du projet, repository de code, instance jenkins, base de données et instance de run). Pour l’instant, quatre types de Click Start sont disponibles (JavaEE6, Hibernate/Tomcat, Rest/Backbone, Scala/Lift).

Du legacy au cloud : David Gageot - @dgageot

David est un excellent speaker que je vous recommande de voir si il est dans une conférence à laquelle vous assistez. Son talk est du pur live coding, sans aucun slide, et reprenait le kata de Gilded Rose où une application existante doit être refactorée.  Une spécification est disponible, mais David ne recommande pas particulièrement de la lire pour commencer mais plutôt de créer des tests sur le code existant que l’on doit retravailler. La logique étant que si l’application convient aux utilisateurs actuellement, le plus important est de préserver son fonctionnement. Les tests sont assez simples à écrire, on appelle chaque méthode et on colle dans le assert le résultat renvoyé : on obtient ainsi une série de tests au vert qui seront notre sécurité.

David utilise le plugin infinitest qui relance les tests dès que le code est modifié : si vos tests sont très courts, le feed-back est immédiat.

La marche à suivre pour refactorer le code est la suivante :

- augmenter la symétrie (mettre les if/else et les equals de la même façon, en enlevant les conditions inversées par exemple).

- puis faire apparaître les duplications de code afin d’extraire de nouvelles méthodes

David finit par introduire de la délégation (un objet était passé dans toutes les méthodes de la classe), en utilisant une annotation de Lombok.

Une fois le code propre, David écrit un petit serveur http qui expose les données en JSON, déploie l’application sur heroku, puis déploie un front statique sur Github Pages (comme le blog de NinjaSquad) qui consomme les données.

Le tout en 45 minutes, en expliquant très bien ses choix et en utilisant IntelliJ avec maestria. C’est la présentation que j’ai préféré de la journée, même si parfois le refactoring était un peu magique, David connaissant bien le code et étant pressé par le temps. Si vous voulez tester le dojo par vous même, les projets sont disponibles sur le compte Github de David.

Beaglebone = Arduino^10 : Laurent Huet – @lhuet35

Laurent nous faisait descendre de quelques niveaux d’abstraction avec un talk sur Beaglebone, une carte plus puissante qu’un Arduino, un peu du même type que le Raspberry Pi. La présentation était intéressante, avec une explication générale des principes, une démo, et les technos que l’on peut faire tourner sur ce type de cartes (C/C++, Java, Python, Node.js …). Manque de chance pour Laurent, sa carte de démo avait grillé la veille (les risques du métiers), mais son talk n’en a pas été trop perturbé, bravo à lui!

Programatoo pour les grands : Audrey Neveu - @audrey_neveu et Ludovic Borie - @ludovicborie

Vous avez peut être entendu parler de Programatoo, un atelier de programmation pour initier les enfants dès l’age de 6 ans aux joies du code. Audrey et Ludovic nous ont montré les différents outils que l’on peut utiliser pour  éveiller la curiosité des plus petits (je ne sais pas si cela peut fonctionner avec vos collègues également) : Scratch, KidsRuby ou encore TortueScript. Très sympa, si vous avez des enfants, ce genre d’outils devraient vous intéresser!

La journée de conf se termine déjà, l’assemblée se dirige vers le port pour un repas tous ensemble. Le JUGSummerCamp aura été une très belle journée, superbement organisée par Jerôme Petit, Orianne Tisseuil et leur équipe. L’équipe Mix-it en partie présente compte bien leur emprunter quelques bonnes idées! Si vous avez l’occasion de vous rendre à la prochaine édition, n’hésitez pas, la conférence, gratuite, est l’une des toutes meilleures en France et la Rochelle et ses alentours ne manquent pas de charme pour rester quelques jours supplémentaires!

Le site Mix-it : making-of

Mix-IT est terminé et beaucoup de participants ont apprécié le nouveau site avec ses facettes communautaires et social gaming. En tout cas, nous avons pris beaucoup de plaisir à le faire. Car oui, ce site a été entièrement développé par les soins de notre équipe, particulièrement par Cyril Lacote (qui, il faut le dire doit avoir 60% du code à lui seul), Agnès Crépet et moi même, aidé par le reste de la team, avec leurs propositions, tests et feedback.

Voici donc une liste non exhaustive des outils et technos utilisés :

Trello : nous sommes des fans de la première heure de cet outil, qui nous a beaucoup servi pour échanger (mes camarades globe trotteur étant toujours décalés de plusieurs heures). Trello permet de faire un scrumboard interactif (on est notifié des échanges sur une tache), temps reel, avec un système de vote, label et filtre. Ça n’est pas JIRA mais pour un outil gratuit, c’est un outil génial.

Github : les sources du projet sont gérées sous Git. Aucun d’entre nous n’est un expert mais nous n’avons pas rencontré de problème majeur passés les premiers réglages. Nous avons utilisé le modèle décrit par Github (voir le talk de Zach Holman, et les articles GitHub), a savoir des pull requests, revues par un autre développeur avant d’être acceptées dans le master. C’est une bonne façon de garder une ‘collective ownership’ du code, même sans commiter.

Cloudbees : l’application est hébergée gracieusement par Cloudbees, qui a de plus acceptée généreusement de nous offrir les services additionnels qui nous était nécessaires (SendGrid, base de données en mode étendu, application en mode On Demand). La plateforme est très bien réalisée, le déploiement prend quelques minutes et est très simple à configurer. Ajoutez à ça un support ultra réactif et le fait qu’un déploiement est invisible pour les utilisateurs et vous avez une plateforme de choix pour vos développements.

Techniquement, l’application est codée avec le framework Play! (1.2.4 à l’heure actuelle) : rien à dire là dessus, Cyril et Agnès ne connaissaient pas et étaient productifs en quelques heures, peu de problèmes rencontrés, et avec tout un tas de modules à disposition (recherche full text Lucene, export PDF, parser Markdown). Bref, un outil génial! Un peu de Guava en plus et nous avions nos briques côté serveur. La base de données est un MySQL (hébergement cloudbees oblige).

Côté client, rien de très original, du bon vieux jQuery pour la manipulation de DOM. Et pour faire la même chose côté serveur (en Java donc), nous avons utilisé Jerry, qui nous permet de manipuler le contenu HTML des posts Google+ pour transformer les mentions d’utilisateurs. Nous avons également utilisé un plugin jQuery bien pratique pour gérer la dirtiness des formulaires et empêcher la sortie des pages en cours d’édition : dirtyforms.

Twitter Bootstrap : probablement notre coup de coeur, car même si nous faisons tous du développement, aucun d’entre nous n’est très doué en CSS. Et là, Twitter Bootstrap peut vous sauver : c’est un bootstrap CSS qui vous donne juste ce qu’il faut de cadre pour faire une application web présentable. Inconvénient : beaucoup de sites utilisent la même chose, il faut donc faire un peu de customisation pour différencier votre site. Tous les icones utilisés proviennent de fontawesome. Nous utilisons la version Less de Bootstrap plutôt que la version CSS : pour plus d’infos voir article précédent.

Ce qui n’a jamais atteint la mise en ligne

Nous avions envie de mettre un peu de communication temps réel sur le site avec un système de notifications lorsqu’un participant auquel vous étiez relié effectuait une action sur le site. Pour ça, un projet annexe (disponible sur github également) utilisant nodejs était utilisé. Dès qu’une action était effectuée sur le site, une requête était envoyée à un serveur nodejs, qui notifiait les utilisateurs intéressés connectés (par websocket en utilisant socket.io). La notification se fait sous forme d’une notification HTML5 si disponible dans le navigateur, ou en utilisant le plugin noty. Malheureusement nous n’avons pas eu le temps de terminer cette fonctionnalité.

Maybe next year… D’ici là, vous pouvez trouver les sources sur Github et vous amusez avec!

So what is Meteor?

Il y a quelques jours, un (enième) framework javascript faisait son lancement : Meteor. Un très bon lancement d’ailleurs, avec un site agréable, 3 petites applications d’exemple, presentées avec des screencasts clairs. Cette sortie est remarquée et se retrouve rapidement commentée sur Hacker News, Twitter et Quora. Car Meteor est un framework de développement d’application web full stack en javascript qui entend bien révolutionner notre façon de coder.


Pourquoi autant d’attention pour un framework vieux de quelques jours ? Parce qu’il y a quelques idées très intéressantes à étudier! Le site annonce la couleur de suite : développer rapidement une application web de qualité dont l’une des qualités, et pas des moindres, est de pouvoir faire du temps réel. Et il faut reconnaitre que leurs démos sont enthousiasmantes : il y a longtemps que je ne m’étais pas dit ‘il faut que j’essaye ce truc!’ en regardant un framework web! Pour avoir fait un petit essai d’appli, c’est simple à mettre en oeuvre, et en une heure j’avais une petite démo qui tournait en ligne (meteor propose son service d’hébergement). L’une des fonctions extrêmement agréable en code est l’auto refresh du navigateur. Play! mettait déjà en avant son cycle de développement rapide, à la portée d’un refresh manuel d’une seconde (enfin ca c’était avant la version 2…). Ici même plus besoin de cette étape, votre navigateur est automatiquement notifié d’un changement et les affiche à l’écran. En dual-screen, c’est un bonheur à coder! Faisons un petit tour sous le capot maintenant.


Real time

Plutot que d’envoyer du html a votre client, Meteor propose d’envoyer seulement les données et de laisser le client décider de la façon dont elles doivent être affichées. La où Meteor donne son effet “wahou”, c’est par sa gestion native du temps réel. L’objet affiché dans votre navigateur a été modifié par un autre utilisateur ? No problem, Meteor va informer tous les clients de cette modification, et vous allez voir votre affichage se modifier en conséquence! C’est vraiment impressionnant d’obtenir un tel résultat sans rien coder, et rien que pour ça, prenez 5 minutes et essayez. D’autres outils proposent également de vous aider à bâtir des applications avec temps réels dont socketstream qui est très bon et s’appuie sur socket.io (le lead développeur de socketstream explique la différence de philosophie, socketstream etant beaucoup plus léger et prévu pour s’intégrer en complément d’autres frameworks). Ici Meteor a fait le choix d’utiliser SockJS, une librairie un peu équivalente. Mais pour l’instant rien ne passe par les websockets, tous les transferts de data sont par requête xhr (dans le code source il est indiqué que c’est par soucis de compatibilité avec les différentes navigateurs, mais c’est évidement modifiable). Tout se passe par un système de publish/suscribe que l’on retrouve de plus en plus et qui est très intéressant (vos clients s’abonnent à des événements qui les intéressent et réagissent en conséquence).


Auto refresh

Lorsque vous êtes en train de développer, la sauvegarde d’un fichier sur votre poste va automatiquement rafraichir le navigateur avec vos modifications. Comme je le disais en introduction, c’est un vrai bonheur et c’est quelque que l’on voit apparaître un peu partout. Ce principe de modification à chaud est aussi disponible en production : Meteor annonce qu’une nouvelle version de votre application peut être déployée de façon transparente pour vos utilisateurs (bon ça je pense que personne n’a vraiment testé…).


Node.js as runtime

Node.js gagne en maturité et devient un runtime vraiment intéressant pour bâtir des applications (pas forcément des webapps d’ailleurs). On trouve déjà des frameworks webs par poignées, l’un de mes préférés étant Express. Celui ci est différent à bien des égards par rapport à ce qu’il existe déjà, par son aspect full-stack et temps réel. Mais un point a dérangé pas mal de monde, une phrase de la doc indiquant : “In Meteor, your server code runs in a single thread per request, not in the asynchronous callback style typical of Node”. L’encapsulation de Node est donc différente de ce à quoi nous sommes habitués dans la majeure partie des cas. Mais tout ça est transparent pour le développeur, et l’équipe derrière a l’air d’avoir une certaine “street cred” (notamment les développeurs d’Etherpad, un Google Docs avant l’heure, d’ailleurs racheté par Google par la suite), donc leur choix n’est peut être pas aussi absurde qu’il peut en avoir l’air a première vue. Cette gestion différente de Node se fait grâce à la librairie node-fibers entre autre. En tout cas, même si vous n’avez jamais fait de Node.js, aucun problème pour se lancer avec Meteor, tout est transparent. Nodejs est d’ailleurs le seul prérequis pour déployer une application Meteor.


Partage du code client et serveur

Meteor est un framework full stack qui donne les outils nécessaires pour faire votre application depuis le templating client à la persistance en base de données. Mais de plus pour Meteor, vos objets javascripts clients sont les mêmes que les objets javascripts serveurs. On dénombre quelques frameworks javascripts qui ont la même idée, comme par exemple Tower.js, voire même des choses assez proches de Meteor comme Derby (beaucoup de features identiques sont présentes, au point que l’équipe de Derby a fait un billet pour expliquer leurs différences). Plus que les objets, se sont même les fonctions qui peuvent s’exécuter indifféremment côté client ou côté serveur!

Le code est à tel point partagé que par défaut, vous écrivez les deux parties dans le même fichier (chaque partie étant quand même identifiée, mais on peut partager des fonctions entre les deux). Vous pouvez également scinder ce fichier, la convention étant de créer un dossier ‘client’ et un dossier ‘serveur’ qui contiennent vos fichiers.


Base de données

Par défaut, c’est une instance MongoDB qui est lancée pour la persistence. MongoDB est une base NoSQL, orientée document, dont l’API est en javascript. Cette API est d’ailleurs disponible aussi bien dans la partie serveur que dans la partie cliente! Hein? Oui, en fait, Meteor va répliquer la base de données dans le navigateur, pour que vous puissiez manipuler un ensemble valide de données directement depuis le client (on imagine bien que ce système a des limites, mais n’est pas trop détaillé à ma connaissance).


Côté client

Le système de templating retenu est Handlebars par défaut, mais il est à priori possible de choisir son préféré. Pour le reste, le comportement ressemble à beaucoup d’autres frameworks à la Backbone : vous définissez à quels ‘events’ vont réagir vos objets et la façon dont ils vont réagir. Pour manipuler le DOM vous pouvez utiliser votre bibliothèque favorite (en interne Meteor utilise JQuery). Ce qui est intéressant c’est qu’une action côté client n’attend pas forcément la réponse du serveur : elle va effectuer son action immédiatement (en simulant la requête, puisque votre base de code fonctionne aussi bien côté client que côté serveur). Quand le serveur renvoie sa réponse, le client compare les résultats et se met à jour en conséquence. Cette fonctionnalité s’appelle la ‘compensation de latence’ et permet également de faire fonctionner Meteor en offline : si votre serveur est indisponible, le client va effectuer tous les traitements localement, donnant l’impression que tout fonctionne normalement. Lorsque la connection est rétablie, les requêtes en attente sont jouées sur le serveur et le client se met à jour. Ce mécanisme est détaillé par l’un des développeurs sur stack overflow.

Le protocole de communication client serveur est de leur cru et baptisé DDP (ce n’est donc pas du REST par exemple, bien que les développeurs indiquent qu’il est simple d’adapter DDP pour en faire du REST, ou le connecter à d’autres protocoles, mais cela manque un peu de doc là encore).


Packaging

Meteor vient avec son propre système de gestion de dépendances et de packaging. C’est bien fait et efficace mais cela ne s’appuie pas sur NPM qui est pourtant devenu le standard de facto de la communauté Node, et qui s’avère très très pratique. Un choix un peu discutable donc. Un certain nombre de packages sont déjà disponibles, dont backbone ou less par exemple. Côté déploiement, c’est vraiment efficace : un simple “meteor deploy” pousse votre application sur le service de hosting maison de Meteor (sur une url etant par défaut lenomdemonappli.meteor.com). Il est possible de sécuriser le déploiement de l’application avec un mot de passe (option -P).

Sécurité

L’un des points non traités pour l’instant, et non des moindres, est la partie sécurité/authentification. Pour cette version, on ne peut tout simplement rien faire dans ce domaine, donc une application mise en ligne peut voir sa base de données vidée en quelques secondes (l’API de la base étant exposée côté client, une petite requête dans la console javascript et c’est plié).

Licence

Un dernier mot sur la licence : Meteor est en GPL, licence virale par excellence. Donc tant que vous faites vous aussi du GPL et que vous redistribuez votre code pas de soucis, sinon vous êtes encouragés à contacter l’équipe de Meteor (entendez, éventuellement payer) pour une utilisation commerciale. Ca n’est pas fondamentalement gênant, et on comprend bien qu’ils veulent gagner leur vie. Bien d’autres outils connus utilisent cette double licence (MySQL par exemple), mais c’est finalement assez peu courants dans les projets Javascript, qui ont habituellement des licences plus permissives. La question qui se pose est : est ce que cela va limiter l’adoption et les contributions à Meteor? Cet article vous expliquera tout ça mieux que moi si le sujet des licences vous intéresse.

Edit : depuis l’écriture de ce post, la licence est passée en MIT. Comme quoi, le pouvoir de la communauté…


J’espère que cet article vous aura fait partager mon enthousiasme pour Meteor, bien que j’explique également les quelques choix qui font débat. Le meilleur moyen de vous faire votre avis est vraiment de regarder les quelques screencasts disponibles. Il y a d’excellentes idées dans cet outil, et nous allons voir de plus en plus de frameworks nous offrir ce genre de fonctionnalités pour faire des applications web bien différentes de ce que nous faisons actuellement.

CSS sucks, do Less!

L’écriture d’une feuille de style est l’un des moments les plus douloureux pour tout développeur Web : la science occulte des CSS et sa verbosité en font une soupe rarement agréable à avaler. Mais un outil peut changer tout ça : Less!

Less est un preprocesseur CSS et n’est pas magique : vous devrez tout de même travailler pour avoir un style graphique convenable. Mais la où il innove, c’est par l’ajout de quelques fonctionnalités bien pratiques, et on se demande comment nous avons pu nous en passer jusque la.

Do Less

Pour démarrer, un fichier css peut être un fichier less : vous le renommez en .less et le tour est joué. Ensuite, pour utiliser ce fichier, plusieurs choix s’offrent à vous. Vous pouvez inclure less.js dans votre page web et le laisser transformer vos fichiers less en css.

<script src="less.js" type="text/javascript"></script>
<link rel="stylesheet/less" type="text/css" href="styles.less">

Ou vous pouvez compiler directement vos fichiers less en css, selon le type de votre application :
- Avec des compilateurs existants comme less.app
- Avec le module less de nodejs
- Si vous faites du Play!, vous pouvez utiliser le module prévu. A noter qu’en Play!2, le support de less est natif, la compilation se fait de façon transparente pour vous. Bref, Less commence à être connu et intégré un peu partout. Le magnifique Twitter Bootstrap par exemple, un super bootstrap css qui vous permet de faire un style sympa même sans rien comprendre à l’art obscur des css, est fait avec Less. Mais bon, Less, ça fait quoi ?

Variables

Que tout ceux qui n’ont jamais pesté pour changer la couleur d’un thème lève la main! Bon, je ne peux pas voir, mais je suis sûr que vous n’êtes pas nombreux. Tout ça à cause de l’absence de variable en CSS. Voyons un peux comment Less remédie à ce problème, et à bien d’autres… Les variables sont nos amies : c’est la première chose que l’on apprend en programmation. On se retrouve un peu démuni en CSS, avec l’obligation de copier/coller n fois la même couleur ou la taille de police, et la galère qui suit pour un changement. Avec Less, c’est fini!Si vous voulez créer un thème, après avoir repéré le code couleur qui vous faisait rêver sur ColourLovers, vous pouvez définir vos premières variables :

@body_color: #262626;
@font_color: #EAF2D9;

On peut également définir d’autres variables, telles que la taille de la police :

@font_size: 20px;

Là où ça devient intéressant, c’est que l’on peut également faire des opérations (pas n’importe quoi hein, juste des opérations mathématiques de base) :

@big_font_size: font_size + 2px;

Fonctions

Si l’on a des variables et des opérations, vous vous doutez que l’on a aussi … des fonctions ! Baptisées “mixins” elles permettent de créer des styles avec des paramètres. Exemple :  les petits bords arrondis sympas que l’on veut mettre sur tous les boutons mais qui sont définis avec des styles spécifiques à chaque navigateur, et que l’on doit répéter à chaque taille d’arrondis que l’on veut.
Less nous permet de créer une fonction border-radius avec un seul paramètre nommé radius

.border-radius(@radius){
 border-radius: @radius;
 -webkit-border-radius: @radius;
 -moz-border-radius: @radius;
}

Cette fonction peut ensuite être appelée dans votre style :

.border-radius(10px);

Et ca devient franchement cool, quand on voit que d’autres ont pris le temps de faire des fonctions à notre place, et que l’on peut utiliser ces fichiers dans nos styles, lesselements ou encore dans le Bootstrap Twitter (oui, je suis fan).

Vous n’aurez plus jamais besoin d’écrire un préfixe navigateur (voir l’excellent screencast de nettuts), et ça, ça n’a pas de prix!

Less inclue lui aussi nativement un certain nombre de fonctions portant sur le traitement des couleurs (saturate, lighten, etc http://lesscss.org/#-color-functions). Par exemple :

fade(@color, 50%);

renvoie une couleur 50% plus transparente. Cool, huh ?

Nesting

Maintenant que nous avons vu les briques de base, on peut se pencher un peu plus sur l’apparence d’un fichier .less. On a l’habitude en css de répéter pour chaque régle toute les classes concernées, ce qui devient vite très verbeux :

.share {
 ...
}
.share .name {
 ...
}
.share .tag {
 ...
}
.share .tag .price {
 ...
}

En less, on peut faire quelque chose de plus simple et plus logique :

.share {
  ...
  .name {
    ...
  }
  .tag {
    ...
    .price {
      ...
    }
  }
}

Ce nesting peut s’appliquer aussi bien aux classes, aux ids et aux éléments.
Le nesting a de plus l’avantage d’inciter a regrouper les règles, ce qui peut vite tourner à l’anarchie dans un fichier css classique (qui n’a jamais ajouté sa règle tout en bas du fichier pour aller vite …).

Import

Toujours dans l’idée d’avoir un style plus clair, il est possible de découper ses fichiers less en fichier plus petits et de faire des inclusions là où ils sont nécessaires. Ainsi, vous pouvez avoir un fichier de variables, avec les propriétés générales de l’application, couleurs, font etc… et un fichier de fonctions utilitaires que vous incluez ensuite dans vos fichiers de style.

@import "variables.less";
@import "utils.less";

Magique non ? Moi je ne peux plus m’en passer !

Il existe bien sûr des alternatives à Less telles que Sass issu du monde Ruby (excellent screencast pour le découvrir) ou Stylus, Cet article met d’ailleurs en avant les différences entre Sass et Less.

Le prochain article reprendra la mini appli nodejs des articles précédents et ajoutera un peu de style en less ! Stay tuned !

Cloud9, Coding node.js in the cloud

Coder du javascript, ca n’est pas forcément simple, et on a toujours besoin d’un bon outil. C’est pourquoi je veux vous parler d’un IDE que j’ai utilisé récemment, et qui change un peu d’Eclipse et d’IntelliJ : Cloud9.

Cloud9 est un IDE un peu particulier : comme son nom le laisse supposer c’est un environnement de développement web-based, open source, écrit en javascript pour faire du javascript. Le back-end est d’ailleurs écrit en node.js, le front est html5 et le tout utilise massivement les websockets, que du hype! Votre code est donc accessible depuis n’importe quel poste de travail, pour peu que vous ayez une connection web, évidemment.

Pour tester rendez vous sur c9.io ou installez le directement dans votre navigateur si vous utilisez Chrome (si vraiment vous n’aimez pas votre navigateur, vous pouvez également récupérer les sources et lancer l’IDE en local). Une fois installé, il faut se connecter : pour cela vous pouvez utiliser votre compte Github ou Bitbucket, ou encore créer un compte cloud9. Le projet utilisé pour cette série d’article étant hébergé sur Github, j’utiliserais donc cette option.

Une fois connecté vous arrivez sur une page d’accueil qui liste les projets de votre compte Github. Pour commencer à travailler, il faut créer ou cloner un projet. La création permet d’héberger son projet directement sur Github, Bitbucket ou un ftp (bientôt sur Dropbox également). Cloud9 adopte un modèle de fonctionnement à la Github : si votre projet est public, l’utilisation est gratuite, si vous voulez faire un projet privé, il faut payer (15$ par mois).

L’IDE permet également de créer des contextes : en haut à gauche, cliquez sur ‘Active context’. Ces contextes permettent de changer rapidement entre vos projets et également de gérer l’aspect collaboratif : il est possible d’ajouter des membres aux différents projets et de travailler à plusieurs (avec modifications temps réel et chat intégré).

Pour faire simple, nous allons cloner le projet du précédent article, pour cela, cliquez sur le ‘+’ à côté de ‘My project’ puis choisissez ‘clone from url’. Entrez alors l’adresse du projet shares : git://github.com/cexbrayat/shares.git. Une fois que Cloud9 a terminé de cloner le projet, on peut commencer à coder en cliquant sur ‘Start editing’ !

La fenêtre qui apparaît ressemble à un IDE traditionnel avec barre de menu, explorateur de fichier et zone d’edition. En bas la zone de saisie sert de console. Si l’on ouvre le fichier app.js, on voit que la coloration syntaxique est présente et agréable. La complétion est elle aussi disponible (et très pratique, mais si elle n’est pas exempte de quelques errements). Le code est également analysé en fond, et des indications vous sont données pendant l’édition. On peut voir par exemple qu’un point virgule est manquant sur la ligne 42 avec un petit warning dans la marge. Beaucoup de raccourcis clavier traditionnels sont disponibles, le debug, l’inspection des variables, bref tout ce dont nous avons besoin. Il est même possible d’ajouter des extensions (et d’en créer) ou de modifier les thèmes (IdleFinger ou Monokai sont assez sympas).

La où Cloud9 se distingue c’est qu’il est réellement pensé pour créer du code et le tester depuis n’importe quelle machine, et particulièrement pour du code node.js. L’intégration de différents composants vont en faire l’un de vos nouveaux amis :

- Github : la ligne de commande (zone de saisie tout en bas de l’écran) vous permet de saisir vos commandes git, avec une autocomplétion bien pratique. Vous pouvez donc directement commiter vos modifications, créer vos branches etc…

- NPM : le gestionnaire de dépendances de node est déjà installé ! Le projet utilisant les modules express et jade, il faut donc les récupérer, pour cela entrez dans la ligne de commande ‘npm install’ et voilà le projet prêt à être lancé.

- Node : évidemment node.js est déjà installé, vous pouvez donc lancer votre projet directement depuis votre navigateur en cliquant sur ‘run’ et en indiquant le fichier principal ‘app.js’. Le projet démarre alors et une url s’affiche en console (pour moi http://shares.cexbrayat.cloud9ide.com/) et me permet d’accéder au projet (ainsi qu’à n’importe qui, voilà qui va simplifier les démos!). La seule modification qu’il soit nécessaire de faire pour lancer le projet est de modifier le port de lancement de l’application par la variable d’environnement process.env.C9_PORT

- Le déploiement : une fois votre application prête pour le monde, vous pouvez la déployer directement depuis cloud9 vers une instance joyent ou heroku.

Les seuls reproches que je lui ferais sont le manque d’outils pour le refactoring et quelques rares plantages (pas beaucoup plus qu’un Eclipse traditionnel cependant. Un troll, où ça ?).

Vous voilà à deux clics de commencer à coder votre première application node.js, sans avoir besoin d’installer moults outils : vous n’avez plus d’excuse pour ne pas essayer !

Trello, encore un peu de Node.js

Cette semaine (le 13 Septembre exactement), FogCreek a annoncé un nouvel outil. Peut être ne connaissez vous pas FogCreek : c’est la société de Joël Spolsky, aussi fondateur de StackOverflow et auteur de l’excellent blog, Joël on Software.

L’outil s’appelle Trello et sert à gérer les différentes tâches de vos projets, à la manière d’un whiteboard avec post-it que l’on deplace. Vous pouvez créer une nouvelle tache, représentée par une carte, l’assigner a un utilisateur, commenter cette tache, y ajouter une liste de choses a faire (avec une barre de progression qui se remplit au fur et a mesure que chaque item de la liste est effectué). On peut également déplacer ces taches entre les différentes colonnes, y ajouter des pieces jointes, des labels, tout ca avec des raccourcis claviers! Lisez le billet de Spolsky a l’occasion du lancement pour avoir plus de détails sur les usages qu’il est possible d’en faire : FogCreek utilise par exemple un ecran 42 pouces pour afficher Trello dans leurs locaux! Un autre article en français si vous êtes allergique à la langue de Shakespeare.

Mais surtout Trello est gratuit, donc foncez vous inscrire et essayer ! On l’utilise depuis quelques jours sur un petit projet, c’est très pratique et fun.

Si vous avez lu le titre de l’article, vous savez que je ne voulais pas seulement vous parler de l’outil Trello, mais aussi des technologies qu’il utilise. Essayez d’accéder à Trello depuis votre téléphone ou de réduire votre écran : la CSS est très bien faite et s’adapte parfaitement quelque soit la résolution d’écran. Un coup de Firebug plus tard, je me suis rendu compte que de plus ca sentait l’application Node.js à plein nez. Effectivement après quelques recherches plus poussées, j’en suis arrivé à une conclusion qui s’est trouvée confirmer par un employé de FogCreek sur son Twitter.

La stack compléte semble être :

- Node.js.

- Module Express.

- Module Async qui permet de faire de l’asynchrone en Javascript (ajoute des focntions map, reduce, filter et du contrôle de workflow).

- Backbone.js et Underscore.js (je vous laisse lire les très bon articles de Philippe Charrière) pour le MVC côté client.

- La partie CSS utilise le module Less (c’est l’objet de mon prochain article).

- Utilisation massive des websockets grâce à Socket.io (vous pouvez le voir en ouvrant de multiples onglets et observer les modifications qui se répercutent – article à suivre également).

- CoffeeScript pour simplifier l’écriture du Javascript et JQuery.

- MongoDb avec Mongoose pour les données persistantes.

- Redis pour les données non persistantes du type session.

- Pour le debug, Node Inspector est évoqué.

A priori le mot d’ordre chez FogCreek c’est de ne pas utiliser une techno qui a plus de 2 ans : so hype ! Spolsky devrait écrire quelques articles dans les prochains jours sur le pourquoi de ces choix, je vous conseille de suivre le blog de Trello si cela vous intéresse. Dans tous les cas, voilà peut être la killer-app de Node.js.

Edit 19/01/2012 : l’article est enfin sorti et confirme la stack décrite ici, enjoy!

Node, Express et Jade

Après un article de présentation et un premier “Hello world”, passons à la suite. Nous avons créé un serveur http basique. Pour créer une véritable application web, il reste encore du travail, à minima créer des pages qui seront renvoyées par le serveur. D’où notre travail du jour :
- créer les vues de l’application,
- créer le routage des requêtes afin de renvoyer la bonne vue.
L’idée est de créer un affichage du cours des actions d’une bourse virtuelle. Pour cela, on ne va pas tout faire nous même. En avant !

Quand je vous disais que Node.js fourmillait de modules, je ne mentais pas. Différentes solutions de moteur de template  s’offrent à vous, ou mieux des frameworks web (qui s’appuient donc sur des moteurs de templating, mais aussi des modules CSS, de routage etc…).

Express  est probablement le framework le plus connu et utilisé. Développé par le talentueux TJ Holowaychuk, Express s’appuie sur Connect  (un framework de serveur http qui regroupe un ensemble de middleware, inspiré de Rack). Le toujours très bon site howtonode en donne une explication intéressante.

Il utilise par défaut le moteur de template Jade  mais d’autres sont également disponibles.
Bien d’autres solutions de frameworks web existent et vous allez trouver des fans de chacune. Si vous avez un module préféré, n’hésitez pas à le signaler en commentaire.

Suivons donc la hype, et découvrons Express et Jade!

Installation express

Comme souvent on trouve moult ressources  pour bien installer Express. Si vous ne l’avez pas déjà fait, je vous conseille d’installer npm (Node Packet Manager), utilitaire très pratique qui se charge de récupérer pour vous les modules que vous voulez et de les installer (vous avez dit Maven ?). L’installation d’Express par NPM se fait alors en une ligne de commande. Une fois Express installé, créez un nouveau projet ‘shares’ avec la commande

express shares

Si vous explorez le dossier créé (ou directement sur Github ), vous trouvez une architecture typique projet web a la Rails/Grails/Play! :
- un fichier package.json équivalent à un pom.xml
- un dossier views pour les vues de l’application
- un dossier public qui contient les différentes ressources (images, styles, js)
- un fichier principal app.js

Ce dernier nous intéresse plus particulièrement, on y trouve deux parties intéressantes :
- la partie Configuration avec déjà quelques modules déclarés
- la partie Routes, qui permettra de définir quelle vue sera renvoyée pour une route donnée.
Le serveur est lancé sur le port 3000, donc si vous avez bien suivi un

node app.js

suivi d’un saut dans le navigateur vous amène à une belle page d’accueil.

Non ? Alors il vous manque peut être quelques modules : comme on le ferait pour un build Maven il faut récupérer les dépendances du projet avant de pouvoir travailler.

npm install -d

s’en charge pour vous. On relance le serveur et voilà !

Ma première route

Nous allons modifier la route existante pour la remplacer par une a nous

app.get('/', function(req, res){
 res.render('shares', {title : 'Shares', shares : shares});
});

Ainsi une requête sur l’url de notre serveur renverra la vue shares à laquelle nous passons un ensemble de variables (qui seront utilisées pour générer la vue d’après le template comme nous allons le voir incessamment).
Ces variables sont donc le titre de la page et un objet qui représente un tableau d’actions, que nous devons donc définir.

var shares = [{name:"Google",price:120}, {name:"Apple",price:132}, {name:"Microsoft",price:92}]

Chaque action est un objet simple composé d’un nom et d’un prix.

Les routes peuvent également récupérer des paramètres de l’url : si on ajoute une route comme la suivante

app.get('/:name', function(req, res){
 res.render('shares', {title : req.params.name,
    shares : shares.filter(function(share){return share.name.toLowerCase() == req.params.name.toLowerCase()})});
});

alors accéder à la page ‘/google’ donnera une page dont le titre est ‘google’ et la seule action listée celle de … Google.
Vous pouvez voir le code modifié ici.

Passons maintenant à l’écriture de ce template !

Un moteur de template qui envoie

Quel que ce soit votre langage/framework préféré, si vous faites du web, il faut bien écrire les pages html. Et il faut reconnaître que c’est rarement la partie la plus excitante, il faut penser à bien fermer ses balises, à choisir des ids et des classes pertinents, tout en se préparant à la grande bataille du CSS qui s’annonce. Boring…

Les rubyistes ont souvent de bonnes idées et on en trouve dans Rails notamment par poignée (quand on est un profane et curieux comme moi, la série de screencast Railscast est une bonne ressource pour découvrir et se tenir informé). L’une de ses bonnes idées se nomme Haml et sa devise donne le ton : "markup haiku". Haml vise à remplacer les gros templates hideux par quelque chose de plus léger (poétique serait quand même un peu exagéré…). Mais nous ne sommes pas là pour parler Ruby. En revanche Haml a un successeur spirituel dans le monde Javascript et il s’agit de Jade (écrit par le même développeur qu’Express, qui est décidément un garçon très occupé). Le plus simple pour comprendre est de voir ça en action.

Vous avez devant vous votre IDE/éditeur de texte préféré, page blanche et vous entrez

html

Une fois compilé par Jade, ce tag se transforme en

<html></html>

Vous voulez ajouter une div avec un id

div#price 12 euros

va donner

<div id=”prices”>12 euros<div>

ou encore plus simplement

#price 12 euros

car le tag par défaut est une div.

On peut également ajouter une classe

div.prices

ou

.prices

donnera

<div class=”.prices”></div>

Besoin d’ajouter un attribut ?

a(href=’/prices’) Prices

donne

<a href=’/prices’>Prices</a>

Oh et j’oubliais, la déclaration de doctype s’écrit avec un ‘triple bang’ (!!!)

Nice ? Un peu de dynamique maintenant. Si nous avons un article avec un prix, et que l’on passe cet objet au template suivant :

#price #{item.price} euros

nous obtenons

<div id=”price”>12 euros</div>

Ces deux screencasts vous emmèneront un peu plus loin dans la découverte si vous le désirez.
Vous avez maintenant installé Express et eu un aperçu de Jade. Il est temps de faire notre premier template Jade pour Express.

Si vous ouvrez le fichier layout.jade présent dans le répertoire view vous trouvez :

!!!
html
 head
   title= title
   link(rel='stylesheet', href='/stylesheets/style.css')
 body!= body

On retrouve la déclaration de la doctype (triple bang), les balises html, head et body bien connues. On voit également comment s’effectue le chargement d’un style, et l’utilisation de la variable title passée en paramètre du template. A l’instar de Ruby, l’indentation est significative : un bloc indenté est un sous bloc du bloc précédent.
Ce layout est utilisé a chaque appel, et body sera remplacé par le template appelé (le template shares dans notre exemple).

Le template index.jade contient la page d’accueil. Elle ne nous sera plus nécessaire nous pouvons la supprimer. En revanche il nous faut créer la vue shares. Pour cela on peut créer un fichier shares.jade ou un dossier shares contenant un fichier index.jade. Cette deuxième méthode est retenue car nous allons utiliser plusieurs fichiers pour cette vue et ils seront regroupés dans ce dossier par soucis de lisibilité.

Voici a quoi va ressembler votre fichier index.jade

h1 Share's price
.shares
 != partial('share', shares)

La balise h1 contiendra le texte “Share’s price” puis une div avec la classe shares contiendra une “vue partielle”. Cette déclaration permet de façon simple de dire au template que pour chaque action de la collection ‘shares’ passée en paramètre, il faudra effectuer un rendu particulier. Ce sous template est créé dans un template annexe nommé ‘share.jade’ :

.share
 .name #{share.name}
 .tag
   .price(id=share.name) #{share.price}$

Ce template va être appelé pour chaque action, et pour celle-ci va créer une div de classe ‘share’ contenant une div ‘name’ avec le nom de l’action et une div ‘tag’ pour le prix. Cette dernière div contient une div ‘price’ dont l’identifiant est dynamique (pour les besoins du prochain billet) et le prix en $.

Si on relance le serveur vous devez avoir à l’écran la liste des actions !

Et pour tester la deuxième route, si l’on accède à la page ‘/google’, nous obtenons :

Vous pouvez récupérer les sources de cet article sur Github

git clone git@github.com:cexbrayat/shares.git

Pour lancer l’application

npm install -d
node app.js

Jade commence à se répandre, on trouve ainsi Scalate qui s’appuie dessus et est disponible comme moteur de template pour vos projets java (on trouve aussi un module Play!). C’est un outil très intéressant et pratique, à suivre et surveiller!

 

La prochaine fois on découvrira plus en avant Express et on parlera CSS !

Getting started with Node.js : Part 2

Après un premier article d’introduction et avant de passer à un premier Hello world (passage obligatoire avant des choses plus intéressantes), nous allons revenir sur le fonctionnement de Node.

Everything runs in parallel, except your code !

Node.js est “single threaded”, il ne garde donc qu’un seul thread pour votre code ! C’est à dire que faire un “sleep” va bloquer votre serveur et, pendant ce temps là, il ne servira de nouvelles requêtes. Pour des actions très consommatrices de CPU, il peut donc y avoir des blocages (ce n’est pas magique non plus!).

Mais, toutes les actions IO sont lancées de manière asynchrone. Donc si l’une de vos actions (par exemple une lecture en base) est bloquante ou prend beaucoup de temps (les actions IO prennent généralement beaucoup de temps par rapport à votre code), alors votre serveur est toujours capable de servir d’autres requêtes. Get it ?

Call me back

La programmation asynchrone avec événement est intimement liée à la notion de callback et est souvent utilisée en Javascript. On retrouve aussi ce principe dans GWT (normal puisque votre Java se retrouvera au final en … Javascript).

En utilisant des callbacks, vous avez la garantie que votre code n’est pas interrompu et que ce callback soit exécuté une fois l’action terminée. Il n’est pas si simple de travailler de cette façon, pas forcément naturelle dans la plupart des langages.

Il est temps maintenant de faire un premier serveur. Tout d’abord vous devez installer Node.js. Comme la procédure varie selon votre OS, je vous renvoie vers l’excellent site howtonode, qui contient un ensemble de ressource pour Node.js dont une très bonne procédure d’installation.

Maintenant, commençons à coder une première application web. Pour cela nous allons avoir besoin :
- d’un serveur HTTP pour servir les pages web,
- d’un routeur pour répondre aux différentes requêtes selon l’URL,
- de différents handlers de requêtes,
- écrire également les différentes pages html pour les handlers afin de renvoyer le contenu au navigateur.

Si vous prenez votre langage favori, certaines de ces tâches ne sont pas nécessaires (votre Tomcat ou Apache HTTP s’en occupe pour vous). Avec Node.js les choses sont un peu différentes, il nous faut tout écrire, notamment le serveur HTTP… Mais vous allez voir, c’est simple et rapide ! Et pour cette première introduction, nous allons nous contenter du serveur.

Mon premier serveur HTTP

Créez un fichier server.js et collez le code suivant :

var http = require("http");
http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Node is hype!");
  response.end();
}).listen(9000);

Et voila votre premier serveur ! Le code est assez explicite : il crée un serveur en local sur le port 9000 qui renvoie une page contenant “Node is hype”. Pour tester, lancer la commande “node server.js” et ouvrez votre navigateur (si vous avez suivi, vous connaissez l’URL).

Le module http est utilisé dans le code. Vous en utiliserez beaucoup dans vos développements, c’est l’une des forces de Node.js : beaucoup de modules existent et font probablement déjà ce que vous voulez faire.

L’autre point intéressant est l’argument passé en paramètre de la fonction createServer(). C’est une fonction ! Pour les habitués de Javascript (ou des langages fonctionnels) rien d’étonnant. Pour les purs Javaistes cela peut surprendre… La fonction passée est une fonction anonyme, elle n’est pas nommée dans le code. On pourrait écrire le même code différemment :

function requestHandler(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Node is hype!");
  response.end();
}
http.createServer(requestHandler).listen(8888);

En fait cette fonction est notre handler de requête et votre premier callback. En effet à l’arrivée de chaque requête, c’est cette fonction qui sera appelée (c’est la partie event-driven/callback de Node.js). Vous voyez donc peut-être comment résoudre le problème des fonctions qui prennent beaucoup de temps et risquent de bloquer votre serveur au début : il suffit d’en faire des callbacks pour que Node.js continue à servir les autres requêtes.

Organiser son code

Vous vous interrogez peut être sur l’organisation du code. Généralement les tutoriaux vous permette de garder toute la logique dans un seul fichier source. Pour une vraie application, même légère, on se retrouve rapidement à vouloir séparer le code. Cela peut se faire assez simplement avec des modules, que vous pouvez utiliser dans votre code. Vous avez vu le module “http”, il est temps de faire votre propre module “server” qui démarrera le … serveur.
Pour cela il suffit de “wrapper” le code existant dans une fonction et d’exporter cette fonction.

var http = require("http");
function start(){
  http.createServer(function(request, response) {
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Node is hype!");
    response.end();
  }).listen(9000);
}
exports.start = start;

Vous pouvez alors faire un autre fichier main.js ou vous utilisez ce module.

var server = require("./server");
server.start();

Simple n’est-ce pas ?
Maintenant que nous savons faire un module et un serveur de base, nous allons pouvoir nous attaquer le plat de résistance. Stay tuned!

Getting started with Node.js : Part 1

Vous en avez peut être entendu parler, l’un des outils hype du moment est node.js. On le voit partout sur les timelines Twitter et de façon plus surprenante, souvent relayé par des javaistes. Node.js est la pour vous aider à coder côté serveur des applications scalables et qui tiennent la charge comme jamais : c’est le fameux C10K problem. C’est un sujet vraiment passionnant, et on trouve quantité de ressources dessus.

Fact 1 : node.js est un outil pour créer des serveur javascript.

Du Javascript côté serveur! Pourquoi un tel engouement me direz vous ? Le Javascript, on connaît à peu près, on en fait souvent côté client avec des librairies géniales… Mais de là à en faire aussi sur le serveur ! C’est lent en plus le Javascript non ?
Niveau lenteur, vous pouvez être rassuré : node.js se base sur l’excellent moteur javascript Google V8, l’implémentation utilisée dans Google Chrome. Donc disons que cela va assez vite (et vous trouverez des pseudos benchmarks qui penchent dans l’une ou l’autre direction). On est finalement pas si loin de Java : Lars Bak, un des contributeurs de V8, a travaillé sur la JVM et Hotspot (et l’un de ses brevets était d’ailleurs dans la contestation d’origine de Oracle vs. Google).

Fact 2 : node.js est un outil pour créer des serveurs asynchrones et non bloquants

Javascript admettons, mais quelle avantage par rapport à mon serveur Apache préféré ?
L’approche historique et basique des serveurs web était de forker un process pour une requête entrante. Lorsque vous avez plusieurs milliers de connexions on se retrouve vite à plusieurs milliers de process. Qui demandent chacun du temps pour le fork (fork latency), de la mémoire pendant leur exécution, des changements de contexte, un scheduler qui doit dire qui peut faire quoi (même si depuis linux 2.6, le scheduler est en O(1)), et bien sûr de les nettoyer une fois fermés.
Apache Httpd utilise ce système de ‘one process per connection’ avec évidemment des subtilités (pre-fork des process, chaque process gère plusieurs requêtes), mais, de façon schématique, on retrouve donc ces problèmes pour un nombre important de connexions.

L’une des solutions plus efficaces était d’utiliser des threads à la place des process, ou en complément (pour en revenir à Apache Htppd, c’est la qu’intervient le fameux mod worker). Mais c’est encore lent sur certains OS. D’où l’utilisation de thread pools : les threads sont créés en bloc au démarrage puis chaque thread est affecté à une connexion. Les problèmes commencent quand vous avez plus de connexions que de threads disponibles : la requête est alors en attente. Pas encore le top niveau scalabilité…

A la différence de notre Apache Httpd, Node.js ne se base pas sur des threads : c’est un serveur asynchrone qui utilise un process monothread et des I/O non bloquants. L’asynchronisme permet au thread d’exécuter des callbacks lorsqu’il est notifié d’une connexion. Contrairement au modèle évoqué ci-dessus, node.js ne réserve pas un thread à chaque connexion, ce qui va lui permettre de tenir de bien plus fortes charges sans problème de mémoire.

Les I/O regroupent les accès disques, accès base de données, accès réseaux, bref tout ce qui prend du temps sur un ordinateur moderne (latence, débit limité etc…). Ici tous les I/O sont non bloquants, c’est à dire que tout appel est effectué en asynchrone, avec un callback qui sera exécuté une fois l’accès réalisé. Et tous les modules pour node.js doivent utiliser ce principe. Heureusement, même si node.js est relativement jeune, on trouve déjà près de 2000 modules disponibles (basés sur common.js et simples à developper)!

Cela permet alors de servir plusieurs centaines de requêtes par seconde sans problème.

D’autres serveurs proposent ce principe et certains depuis des années :
- nginx (prononcé EngineX) par exemple. Avec des performances intéressantes. Lighttpd lui est souvent comparé (merci à @jponge).
- Twisted aussi pour les fans de Python.
- EventMachine pour les rubyistes.
- En Java, on se tourne vers JBoss Netty, Apache Mina ou Deft (ou Loft, un portage de deft en Scala, merci à @samklr). NIO2 se profilant à l’horizon, les serveurs Java n’auront peut être plus grand chose à envier à node.js. Même JavaEE, avec la spécification Servlet 3.0 et le support de l’asynchronisme suit ce chemin.

Fact 3 : node.js est multi OS

La plupart de ces serveurs se basent, comme node.js, sur l’instruction Unix select (ou des équivalents améliorés comme epoll voire des non POSIX comme kqueue) pour être notifiés d’une nouvelle connexion avant de se rendormir. Et quid de Windows ? C’était justement la nouvelle de ces derniers jours : Microsoft va supporter la société Joyent, où travaille le créateur de node.js, Ryan Dahl, pour un meilleur support de leurs OS.

Voilà comment faire un premier article sur node.js sans en montrer une seule ligne !
Il est probable que vous n’ayez que rarement à traiter 10000 users en parallèle : mais si c’est le cas node.js est un outil intéressant à connaître. Au delà de node.js en particulier, il devient illusoire de pratiquer le métier de développeur web sans connaître un minimum de Javascript. Node.js m’a donné envie de m’y remettre et c’est déjà ça !

Si vous voulez voir comment faire des websockets facilement avec node.js et continuer la découverte de cet univers foisonnant, stay tuned !

Suivre

Recevez les nouvelles publications par mail.

Rejoignez 967 autres abonnés