Retour d’expérience sur le framework NodeJs Sails

Le 17/05/2016

Dans Développement

Aujourd'hui, je vous propose de lire un retour d'expérience sur un framework NodeJS sympathique et plein de tentacules : Sails.
Pour un projet, j'ai dû choisir un framework NodeJS et j'ai eu envie d'essayer Sails js. Quelques mois plus tard, je vous propose de revenir sur les points "remarquables" du framework.

En quelques mots, sachez qu'il s'agit d'un framework VMC aux inspirations assez proches de Rails et construit entièrement en Javascript. Complet sans trop en faire, il avait de bons arguments pour me donner envie de l'essayer.

Pourquoi Sails ?

Pour ma part, le choix du framework Sails.js a été decidé grâce à plusieurs facteurs. 

Tout d'abord, le fait qu'il me laisse choisir ma base de données sans m'imposer MongoDB a été un très bon point. Même si le NoSQL peut avoir des avantages pour certains projets, j'aime être souple sur le point et être capable de m'adapter à mes besoins et pas aux contraintes de dépendance de mes outils.

Ensuite, son aspect strict et rangé m'a beaucoup plus et m'a immédiatement rappelé Rails et l'écosystème Ruby.

Enfin, la documentation en apparence complète m'a rassuré. Ce point était malheureusement un piège et j'ai dû lire pas mal de code pour m'en tirer, mais cela fait partie des raisons qui m'ont poussé vers ce choix.

Si vous êtes à la recherche d'un framework très structuré pour Node Js, et que vous n'avez pas un besoin de performance extrême (je n'ai pas eu de problème sur ce point, mais j'ai lu quelques articles se plaignant de la vitesse de Sails), Sails vous plaira peut-être à vous aussi.

Mon avis sur le Framework

Pour une fois, je vais mettre ma conclusion tout en haut de l'article, pour nuancer un peu le reste de l'article. À la relecture, je me trouve un peu dur avec ce framework qui l'un dans l'autre m'a beaucoup plu. 

Bien sûr, la documentation n'est clairement pas nécessaire, et il faut s'attendre à tomber dans des pièges de temps à autre tendus par cette dernière mais n'est-ce pas le cas de toutes les documentations de l'écosystème Javascript ? Les ressources sortent et évoluent trop vite pour que les documentations suivent, ce qui est inacceptable mais malheureusement commun dans cette communauté.

L'ORM me pose quelques soucis, mais il est certainement possible de le remplacer, tout comme il est possible de créer ou adapter une administration existante pour remplacer l'expérience très désagréable qu'a été Sails hook Admin panel.

Au final, beaucoup de choses m'ont dérangé dans ce framework, c'est vrai, mais je sais déjà que je le réutiliserais sur le prochain projet nécessitant Node Js. Je vous encourage donc à l'essayer pour vous faire un avis par vous-même.

L'aspect général du framework

Rien à redire sur ce point, Sail est très intelligemment organisé et très agréable à manipuler. Fournis avec des standards qui plairont au plus grand monde (Javascript op coffee, scss ou sass, ejs), il ne nécessitera pas de configuration sur ce point pour la plupart d'entre vous (personnellement j'ai choisi de remplacer ejs par Jade Pug).

L'application est organisée en 4 grands dossiers principaux :

  • Config (pour les routes, les initializers, …)
  • Views
  • Assets
  • Api (models, controllers, policies, …).

 

Pour ce qui est des fichiers, beaucoup d'informations passent par leur nom, ce qui force une certaine rigueur de nommage bienvenue. Les assets sont pris en charge par une configuration Grunt simple à comprendre et à modifier, mais malheureusement trop peu documentée à mon gout.

L'ORM : Waterline

Disons le tout de suite, Waterline n'est pas un excellent ORM. Certaines idées sont très intéressantes mais trop peu documentées, et certains points sont simplement vraiment trop restrictifs à comparer à d'autres ORM.

Une des idées intéressantes se situe au niveau de la modification de la base de données. La plupart des ORM fonctionnent avec des fichiers de migration à écrire soi-même ou générer avec un outil, mais Waterline a pris une position bien plus radicale : à chaque démarrage de l'application en développement, l'ORM modifie le schéma de base de données pour correspondre aux models. 

Évidemment, c'est plus "simple" comme ça et même assez agréable à manipuler, mais ce fonctionnement pose pour moi d'assez gros problèmes, comme par exemple des pertes de données quand on travaille en équipe. Dommage que les développeurs n'aient pas opté pour une solution entre-deux, où il aurait été possible de générer des fichiers de migrations en fonction des modifications apportées aux models.

Ensuite, petit point ennuyeux à déclarer, Waterline est obligatoirement asynchrone. Là où la plupart des ORM en Javascript proposent des appels sync ou async, nous n'avons pas cette liberté avec Waterline. Ce point n'est néanmoins pas très grave et une simple lib comme "async" règle très bien ce besoin.

Enfin, et c'est le point le plus "grave" pour moi : chainer les models est extrêmement complexe. Prenons un exemple simple : un modèle "Artist" a une liaison "has_many" sur un modèle "Album", qui à lui un "has_many" sur "Song". Il sera impossible de faire quelque chose approchant "Artist.find({id: 1}). albums[0].songs" (ce code est évidemment non fonctionnel, c'est une illustration). La seule solution sera de rechercher les albums ayant la bonne valeur de artist_id, puis d'accéder à l'artiste et aux chansons depuis là.

Ce point peut sembler anecdotique, mais sachez bien qu'à l'utilisation, il se retrouve totalement contre-intuitif et nous met parfois dans des situations bien plus complexes que mon exemple. 

Les controlleurs

Rien de particulier à dire sur ce point, si vous avez déjà manipulé express vous ne serez absolument pas perdu. Seul petit reproche, il n'est pas possible d'exécuter des filters avant ou après plusieurs actions d'un ou plusieurs controllers. Nous sommes donc obligés à utiliser des policies pour cette tâche, ce qui n'est pas leur rôle.

Les routes

Rien d'exceptionnel ici, mais le minimum syndical est fourni. Je ne m'attarde donc pas sur ce point.

Les policies

Les policies sont une idée intéressante, sorte de before action pour ceux d'entre vous qui ont déjà manipulé Rails. Leur rôle est de gérer les différentes autorisations nécessaires pour accéder à une page (l'utilisateur et connecte, la ressource lui est accessible, …), et cette organisation est vraiment intéressante. Seul problème, ces policies sont les seuls moyens à notre disposition pour exécuter du code avant chaque action, et il est donc vraiment tentant de les utiliser de manière un peu moins organisée.

Une interface d'administration ?

En cas d'un projet en Ruby, je sais que j'aurais accès à une administration de qualité que je choisisse Rails (Rails Admin) ou que je choisisse Padrino (Padrino Admin). C'est donc avec stupeur que j'ai découvert qu'il n'existe RIEN de satisfaisant pour Sails (ou pour express en général, soyons réaliste). La seule solution agnostique et simple à mettre en place que j'ai trouvé et Sails Hook Admin Panel, mais attendez-vous à bricoler : la pagination est défectueuse, les checkboxes ne marchent pas, et j'en passe.

Ce point est peut-être ma plus grosse déception sur le Framework.