Node.js

démystifié

Un atelier de Christophe Porteneuve à Paris Web 2014

TÉKITOA


var christophe = {
  age:        36.94794520547945,
  city:       'Paris',
  company:    'Delicious Insights',
  trainings:  ['JS Total', 'Node.js', 'Git Total'],
  jsSince:    1995,
  claimsToFame: [
    'Prototype.js',
    'Ruby On Rails',
    'Bien Développer pour le Web 2.0',
    'Prototype and Script.aculo.us',
    'Paris Web'
  ]
};
          

En 3 heures

On y croit !

Découvrir ce qu’est Node et d’où ça vient

Tester la température de l’eau avec un petit programme

Faire un vrai serveur web bien démonstratif

Aller plus loin…

Historique de Node

En 30 secondes mais sans lapins

  • 2009 : Sortie officielle (0.2)
  • 2010 : Express ; Nodejitsu
  • 2011 : npm ; Azure
  • 2013 : Déferlante de success stories : PayPal, Walmart, LinkedIn, eBay, Yahoo!, Groupon, Medium, Uber…
    Dans la Valley, Rails est devenu le choix « conservateur » et Node.js le choix « start-up moderne ».
  • 2014 : La France l’ignore toujours superbement

Install!

Ça va bien se passer

Node.js

OSX Debian/Ubuntu Windows

Git

OSX Debian/Ubuntu Windows

mongoDB

OSX Debian/Ubuntu Windows

L’atelier

Par Git :

$ git clone https://github.com/tdd/atelier-node-pw2014.git

Ou en téléchargeant l’archive

Hello Node

Soulever le voile

Mon premier programme Node


var os = require('os');

console.log("Salut tout le monde !");
console.log("Cette machine a", os.cpus().length, "processeurs et",
  os.totalmem() / (1024*1024*1024), "Go de RAM");
            

$ node hello.js
Salut tout le monde !
Cette machine a 4 processeurs et 8 Go de RAM

npm

Le référentiel de modules

210 nouveaux modules par jour ! (~100 000, là…)

Omniprésent pour vos outils : Grunt, Gulp, Broccoli, Brunch, Angular, Ember, PhantomJS, CasperJS, Weinre, Cordova/Phonegap, Mocha…

$ npm install --save moment

1er module tiers

Moment.js c’est le bien


var os = require('os');
var moment = require('moment');
moment.locale('fr');

var now = moment();
console.log("Salut tout le monde !");
console.log("On est", now.format('dddd D MMMM YYYY à HH[h]mm'));
console.log("Cette machine a", os.cpus().length, "processeurs et",
  os.totalmem() / (1024*1024*1024), "Go de RAM");
            

$ node hello.js
Salut tout le monde !
On est samedi 18 octobre 2014 à 14h58
Cette machine a 4 processeurs et 8 Go de RAM
            

Un vrai serveur

En voiture Simone !

Express

Le principal framework web de base

C’est une surcouche du module connect qui gère les piles de middlewares, lui-même construit par-dessus le module natif http de Node.

Système d’applis modulaires, routage par méthode et chemin, système de vues et moteurs de templates.

On va aussi utiliser colors pour formater un peu nos affichages en console…

Logging

Avec morgan

Histoire d’avoir des logs HTTP basiques pour bien voir nos requêtes, on va rajouter un middleware « natif » (quand même un module à part) : morgan.

Propose plusieurs formats pré-définis, souvent inspirés d’Apache, et bien sûr on peut définir nos propres formats.

C’est aussi l’occasion de découvrir app.get(…) et le réglage 'env' d’Express.

Templating

Avec Jade

Langage de templating à indentation significative

Un peu comme HAML et Slim

Mécanisme d'extensions et de blocs, plus balèze qu'une simple inclusion dans un layout

Il faut indiquer à Express un moteur par défaut

(et par défaut, Express lit ses vues dans views/…)

Recharger

le code avec nodemon

Ctrl+C / Flèche haute / Entrée, ça va bien 5 minutes…

Nodemon permet de relancer une commande dès que la surveillance de fichiers détecte un changement

Pas que Node, en fait. Très puissant et configurable.

Scripts

du package.json

On peut configurer des actions dans package.json

Certaines sont déjà reconnues : start, test, etc.

On fait alors juste npm start, par exemple.

Pour les autres, npm run le-nom

Ça inclue automatiquement ./node_modules/.bin dans le PATH

Déboguer

Avec node-inspector

console.log aussi, ça va bien 5 minutes pour déboguer…

Et si on utilisait plutôt les DevTools de Chrome ?

C’est possible grâce à node-inspector

Pensez à lancer votre node / nodemon avec --debug

Sessions signées

Dans les cookies, avec cookie-session

Sur ce coup, on va laisser la session en cookie

(ça nous évite d’avoir à la persister côté serveur…)

Mais on va la sécuriser un minimum, en la signant.

Le module cookie-session, dérivé de keygrip, est parfait pour ça

(pour une persistance serveur, express-session et connect-redis marchent bien…)

Les commentaires

Construire l’UI

On va permettre la saisie de commentaires / textes libres, qu’on authentifiera à terme.

Évidemment, il faut donc persister ça « en base »

On utilisera à terme mongoDB, mais pour le moment, posons déjà le contrôleur et les vues…

Protection CSRF

Avec csurf

Afin d’éviter tout risque de CSRF, protégeons-nous avec le module csurf

Il faut du coup bien penser à inclure le token approprié dans tout formulaire qui ne fasse pas juste du GET.

Workflow

à coup de flashes et de redirections

Avant de persister à proprement parler, on peut déjà caler l'UX et les navigations.

Un commentaire valide (non vide) donnerait un message de confirmation suite à une redirection sur la liste.

Un commentaire vide afficherait directement le formulaire, et un message de refus.

Ces messages sont temporaires : on parle de flashes

Voyons comment utiliser connect-flash.

Rien à voir avec Adobe Flash, évidemment…

mongoDB

La techno qui t’aime

Une des principales bases « NoSQL ».

Extrêmement puissante et performante.

Comme pour plusieurs autres, son langage naturel est JS !

Commençons par voir en CLI notre mongoDB et sa manip…


$ mongo
MongoDB shell version: 2.6.3
connecting to: test
>

Mongoose

Le meilleur moyen de faire du mongoDB

Un enrobage très sympa autour de l'API nue de mongoDB.

Fournit des schémas (et donc de la validation, des accesseurs et attributs virtuels, des valeurs par défaut, etc.)

mongoosejs.com

Connexion

à mongoDB

On va se coller une connexion singleton avec un callback de mise à disposition, et ajouter ça à notre démarrage serveur.

Tant que la connexion n’est pas disponible, toutes les opérations sur les modèles resteront en suspens…

Modèle mongoDB

pour nos commentaires

Définissions un schéma pour Comment.

Voyons l’API de requête, notamment en mode promesse.

Faisons une vraie persistance et contrôlons dans la CLI !

Ajoutons une méthode statique de listing…

…et on finit en faisant un vrai listing…

Helpers

pour nos vues

C’est le moment d’augmenter l’infra de helpers qu’on avait faite pour les flashes, en injectant des helpers libres dans nos vues.

Ici, un formateur d’horodatage pour nos commentaires.

Pour se caler automatiquement sur la langue préférée définie dans le navigateur, on va s’aider d’underscore.

Authentification

Avec Passport

Le module dominant pour la gestion générique de l’authentification en Node.

Fournit un middleware d’extension de requête avec une propriété user, un mécanisme de (dé)sérialisation dans la session, et des stratégies à brancher suivant les modes d’authentification retenus.

passportjs.org

Un modèle User

pour nos identités

Il nous faut impérativement des objets qui représentent nos utilisateurs, pour Passport. Comme on veut se souvenir de leur première connexion (si on veut des stats, toussa…), on va les persister.

Donc hop, un modèle Mongoose !

Notre workflow

d’authentification

  • Toute URL démarrant par /comments nécessite une authentification : on va la requérir nous-mêmes.
  • Sur /get-in, on aura une liste d’identifications possibles
  • Sur /get-in/xxx, on aura les accès d’une stratégie xxx
  • Sur /logout, on se déconnecte
  • La barre supérieure des pages soit permettra de se connecter, soit rappellera l’utilisateur actif et permettra de se déconnecter.

Stratégie locale

d’authentification

C’est à nous de dire oui ou non…

On va se faire un truc pipeau : tout login est valide si le mot de passe est « foobar »

Tout utilisateur est créé à la volée la première fois (juste pour notre atelier, hein…).

Des auteurs

pour nos commentaires

Puisqu’on a maintenant un utilisateur actif, autant en faire formellement l’auteur du commentaire lors de la création !

Ça introduit le concept de relation, qui sera ici dénormalisée.

On en profitera pour voir la fonctionnalité populate de Mongoose…

OAuth Facebook

pour l’authentification

À présent que l’infra est en place, ajouter une stratégie est un jeu d’enfant ! Il nous faut :

  1. Configurer et enregistrer la stratégie associée (ici on passe par le module passport-facebook)
  2. Une proposition dans /get-in
  3. Des URLs dédiées (ici OAuth : une URL de demande, une de callback)

OAuth Twitter

pour l’authentification

Quand on a déjà de l’OAuth, en rajouter est super simple !

Il suffit de décliner ce qu’on a fait pour Facebook.

C’est principalement la configuration qui change.

On utilisera passport-twitter.

Temps réel

Avec socket.io

Web Sockets = canal binaire bidirectionnel temps réel, entre le serveur et ses clients.

Pas toujours pertinent, il faut vraiment avoir besoin de bidirectionnel et de temps réel, sinon des moyens plus classiques suffisent.

Trivial en Node grâce à Socket.IO.

Fournit une gestion de fallbacks et une grosse surcouche fonctionnelle (événements, canaux, etc.)

On utilisera serve-static pour servir automatiquement nos fichiers JS.

Plus loin avec Node

Docs API Node

Nouvelles docs npm

NodeSchool (plein de workshops, au top)

Awesome Node.js (celui-ci et celui-là)

CodeSchool

Envie d’en savoir plus ?

On fait des super formations de ouf sur
Git, JavaScript et le dev web front et Node.js.


Et ce qui est encore plus cool, c’est que pour l’auditoire Paris Web, c’est −15% jusqu’à fin janvier :

bit.ly/pw14love

Merci !

Et que Node soit avec vous


Christophe Porteneuve

@porteneuve

Retrouvez les slides sur bit.ly/nodeyoulove

mais aussi le code source annoté complet

et enfin le dépôt complet sur GitHub.