Expérimentation avec Node.JS

Auteur(s) de l'article

Cela faisait un moment que je voulais développer un projet "réel" en Node.js et pas simplement des mini-scripts à droite à gauche pour, par exemple, exposer une micro API, faire office de proxy ou pour créer un script pour Hubot. J’ai donc profité de développer en Node une idée de projet personnel dont vous allez sûrement entendre parler sur ce blog plus tard.
Voici mon compte rendu sur ce que j’ai appris, mon ressenti général sur le langage et la plateforme ainsi que sur les modules que j’ai utilisés.

Node.js ?

Node.js est une plateforme basée sur la machine virtuelle V8 de Chrome pour exécuter du code Javascript côté serveur. Node.js est spécialement connu pour son modèle événementiel et sa gestion non-bloquante des entrées/sorties. Idéal pour les applications réseau (temps réel, data-intensive, streaming, etc), Node.js permet d’écrire des applications javascript du côté serveur.

Retour d’expériences

Globalement ce fut une expérience très enrichissante et plaisante. J’ai rapidement pu avoir un prototype fonctionnel sans être bloqué des heures et j’ai trouvé suffisamment de documentation pour mes besoins. J’ai toutefois eu quelques surprises car l’environnement et l’éco-système de Node.js est encore “jeune” et certaines API ne sont pas encore figées (alors que tout le monde les utilisent déjà). C’est un peu surprenant au début mais on s’y fait vite et il ne faut pas en avoir trop peur car nous pouvons s’en prévenir en figeant plus strictement les versions des dépendances que l’on utilise dans le projet. Je ne connaissais d’ailleurs pas la commande npm shrinkwrap.

Javascript

Ca se confirme, c’est un beau langage :smile: Je l’avais redécouvert à l’époque en développant des applications avec Backbone.js et c’est encore plus plaisant quand nous n’avons pas affaire au DOM et que nous ne subissons pas les aléas des Browsers Support. Là où cela devient encore plus sympa c’est lorsque nous utilisons Javascript comme un langage fonctionnel.

Synchrone vs Asynchrone

Normalement, je travaille majoritairement avec PHP où nous sommes plus dans un modèle synchrone (les instructions s’exécutent les unes après les autres). Avec Node.js nous privilégions le modèle asynchrone où rien (ou presque) ne doit être bloquant. La lecture d’un fichier, l’accès à une base de données ou une requête HTTP se réalisent de manière asynchrone.
Pour y arriver nous utilisons les callbacks. Un callback est une fonction définie par l’utilisateur (développeur) qui sera appelée une fois que la tâche “qui prend du temps” est terminée. Pour que les différents modules et librairies de Node puissent être utilisés ensemble, Node.js a mis en place le standard “Error-first callback” où chaque callback respecte la signature de fonction suivante : function (err, result). Le premier argument est toujours l’erreur ou la valeur null en cas de succès.

À ce sujet, les librairies suivantes m’ont bien aidé:

  • async qui permet de transformer des fonctions javascript natives synchrones sur un modèle asynchrone.
  • Q une implémentation Javascript des Promises

Stream

Bien que je pense avoir compris le principe de base des Streams en Node.js, il me reste encore une bonne marge d’apprentissage pour bien exploiter ce concept dans mes futures applications. Je me réjouis de devenir un vrai plombier en masterisant les pipe()pump() et autre méthodes de canalisation de flux :smile: !
<script src="https://gist.github.com/gido/2995cfbee73ab9789cca.js"></script>
Si ça, ça vous vend pas du rêve ! (source)
Pour aller plus loin:

Framework ?

J’ai basé mon application sur Express, un framework web minimaliste qui fonctionne très bien. La version 4 du framework a été allégée et une bonne partie des fonctionnalités qui étaient dans le Core a été extraite en modules ou middleware (gestion des sessions, des cookies, bodyParser, etc).
Mes données sont stockées dans une base MongoDB et la librairie Mongoose n’est pas trop mal.
Il me manque encore une bonne librairie pour gérer les formulaires, j’ai pas trop cherché et j’ai laissé de côté cet aspect pour le moment. Donc si vous avez une bonne librairie à me recommander, je suis preneur !

Gestionnaire de dépendances

NPM (Node Package Manager) le gestionnaire de paquets de références pour Node.js (et javascript en général) est impressionnement bien fourni et fonctionne à merveille.
Voici la liste des paquets principaux que j’ai utilisés:
  • underscore / lodash – une librairie utilitaire en javascript. (Bonne nouvelle, les 2 projets sont en discussion pour être fusionnés)
  • async / Q – librairie pour travailler le javascript asynchrone
  • request – une librairie pour effectuer des requêtes HTTP
  • swig – un moteur de template qui reprend les concepts de Twig ou Jinja2
  • passport et ses différentes stratégies – permet de gérer l’authentification simplement avec une intégration du protocole OAuth 2.0.
  • dotenv –  Très utile lors du développement, cette librairie permet de charger des variables d’environnement définies dans un fichier texte

Deploiement

Puis est venu la question du déploiement. Déployer une application Node.js peut se relever délicat dans le sens où ton application est le serveur web. J’ai plus l’habitude de déployer des applications PHP qui se trouvent derrière un serveur web déjà en place.
Le plus simple est certainement d’utiliser des services de cloud hosting qui supportent les applications Node.js (Heroku, Nodejitsu, Appfog, etc).
Pour ma part, je voulais héberger l’application moi-même pour mieux comprendre ce que cela impliquait et bon, c’est un projet personnel, j’en ai profité pour apprendre de nouveaux outils.
J’ai choisi la solution Dokku, un mini-heroku à héberger soi-même qui se repose sur Docker et complètement écrit en Bash (oui, voici la preuve que nous pouvons faire de très jolies choses avec bash). Facile à installer, compatible avec les buildpacks Heroku et possède un joli lot de plugins. Parfait pour mon utilisation !

Conclusion

J’adhère à la philosophie d’utiliser le bon outil pour la bonne tâche et je dois dire que Node.js a clairement sa place dans ma boite à outils. Node.js excelle dans bien des domaines.
Je reste encore bien plus performant avec PHP (j’aurais surement écris la meme app avec Silex/Symfony en beaucoup moins de temps) mais l’apprentissage de ce nouvel environnement a été plutôt doux et m’encourage à l’approfondir.