Archives pour la catégorie Node.js

Streams et Node.js : mongoose vers Amazon S3 ou fichier

Mongoose, ODM dont la réputation n’est plus à faire pour s’interfacer avec une base MongoDB, permet de lancer des requêtes sur des milliers de données, et de lire le résultat sous forme de stream.

Rapide rappel sur les Streams Node.js :

Il faut voir les Streams comme des entonnoirs : on peut les imbriquer comme des légos (grâce au pipe).

  • Certains permettent de lire : StreamReader, ils envoient l’eau
  • d’autres d’écrire : StreamWriter, ils récupère l’eau reçue
  • et d’autres sont les 2 à la fois : Duplex et/ou Transform, il reçoivent l’eau, peuvent la nettoyer (Transform) puis la renvoyer

L’entonnoir est imagine qui n’est pas anodine : si on verse de l’eau trop vite dans un entonnoir, elle s’accumule sans avoir le temps de passer. Le parallèle de ce phénomène avec les Streams est ce qu’on appelle la « back pressure« . C’est ce qui se passe le stream qui lit va plus vite que celui qui écrit.

Voyons ça dans un exemple…

Continuer la lecture de Streams et Node.js : mongoose vers Amazon S3 ou fichier 

Terminal : ouvrez vos onglets via un script bash

Travaillant sur une application SPA , j’ai besoin de démarrer mon environnement chaque matin.

j’ai donc besoin de 3 onglets :

  1. application serveur Node.js (node start)
  2. application cliente (gulp)
  3. Shell MongoDB

Voici donc un script permettant d’ouvrir 3 onglets de terminal et de lancer les commandes respectives dans chaque onglet :

Continuer la lecture de Terminal : ouvrez vos onglets via un script bash 

Validateur asynchrone avec Mongoose

Comment valider un champ de son modèle en asynchrone avant de l’enregistrer ?

Prenons le cas suivant : on a un modèle Mobilhomes et un modèle Marque.  On utilise mongoose pour enregistrer un mobilhome.

Ici, je n’utilise pas les ref dans le schéma, mais on pourrait le faire (cf http://mongoosejs.com/docs/populate.html).

var MobilHomeSchema = Schema({
  _id: Schema.Types.ObjectId,
  marque: {
    _id: Schema.Types.ObjectId,
    lib: String
  }
});

var MarqueSchema = Schema({
  _id: Schema.Types.ObjectId,
  lib: String
});

Le souci est que lorsqu’on enregistre un mobilhome avec un ID de marque « bidon », pour valider que l’ID existe bien et qu’un petit malin ne s’amuse pas à essayer d’enregistrer un ID bidon, on veut valider la donnée.

Il faut donc aller chercher dans la collection Marque, si l’ID existe ou non.

On a créé un validateur « custom » mongoose, qui se déclenche au validate(). Dans ce validateur, on fait un marque.findById(ID_A_VALIDER, callback) => ARGH ! on ne récupère le résultat du findById qu’en asynchrone, dans le callback, trop tard pour le validateur mongoose ! En gros, le validateur aurait besoin de savoir, en synchrone, si l’ID existe ou non….

var MobilHomeSchema = Schema({
  _id: {
      type: Schema.Types.ObjectId,
      validate: myCustomValidatorFunction
  marque: {
    _id: Schema.Types.ObjectId,
    lib: String
  }
});

function myCustomValidatorFunction(val){
   // supposons que Marque soit défini, que ce soit un modèle mongoose
   Marque.findById(val, function(err, item){
     if (err) handleError(err);

     // et là, qu'est-ce qu'on fait ?? on retourne TRUE ou FALSE ?
     // ben non... c'est trop tard...
     // 'suite' a déjà été affiché ! Vive l'asynchrone...

     // le code suivant ne sert évidemment à rien :(
     return (item != null);
   });

   console.log('suite');
}

La solution est donc, comme assez souvent avec l’asynchrone, que la librairie nous a prévu le coup ! Le custom validator peut attendre un second paramètre, qui est un callback que mongoose utilise pour traiter des validateurs asynchrones. Bon c’est écrit noir sur blanc dans la doc, mais ça mérite un petit exemple (http://mongoosejs.com/docs/api.html#schematype_SchemaType-validate) :

function myCustomValidatorFunction(val, respond){
   // supposons que Marque soit défini, que ce soit un modèle mongoose
   Marque.findById(val, function(err, item){
     if (err) handleError(err);

     // ici, on appelle le callback avec un booléen en paramètre, résultat de notre validateur
     respond(item != null);
   });
}

Installer Node.js via nvm (permet de le multi-versions)

Vous pouvez installer une version fixe de node, mais ça devient vite pénible de le mettre à jour, et si vous devez utiliser plusieurs versions selon les projets, n’en parlons pas…

Bref, nvm est là pour ça, il permet d’installer différentes versions et de basculer de l’une à l’autre par une simple ligne de commande.

Continuer la lecture de Installer Node.js via nvm (permet de le multi-versions)