Sails.js : un framework NodeJs pour une application MVC

sails logo

Présentation

Le framework Sails.js permet de créer rapidement une application Web avec une architecture MVC reprenant le base Ruby On Rails pour l'adapter à un serveur NodeJS.

Les points mise en avant dans Sails.js :

  • Un ORM simple pouvant être utiliser avec n'importe quelle base de données, il suffit d'employer l'adaptateur qui correspond à la base de données ciblée
  • L'API RESTful JSON est automatiquement générée par Sails.js
  • Un système de sécurité comprenant authentification, rôles et stratégies de permissions flexibles, personnalisables et utilisable dans les cas d'applications temps réel
  • Les requêtes Socket.IO sont directement mappées vers les contrôleurs associés de façon transparente
  • Optimisation automatique des CSS et Javascript lors de la mise en production via la minification des ressources

Pour ce faire Sails.js se base sur :

  • ExpressJS : framework de création d'applications web en NodeJs
  • BluePrint : Il permet de générer automatiquement des Api Json des appels CRUD du modèle, ainsi qu’un routing automatique des contrôleurs.
  • SocketIO : Module NodeJs pour les communications via les websockets
  • Waterline : ORM utilisé par Sails.js
  • EJS : Librairie de templating Javascript utilisé par Sails.js pour la création des vues
  • Grunt : Pour l'exécution de tâches automatiques javascript

Avant de commencer

Pré-requis

Avoir NodeJS d'installé.

Installation

utilisez la ligne de commande

 npm -g install sails

La version release disponible au moment de l'écriture du post est la 0.9.16

Première application

Créer

Pour créer un nouveau projet Sails.js, il suffit d'utiliser la ligne de commande au niveau de votre répertoire de travail de votre nouvelle application

 sails new monNomDeProjet

BRAVO vous avez votre première application Sails.js Pour tester si votre application a bien été créé dans le nouveau répertoire de votre application exécutez la commande:

 sails lift

Ceci démarre un serveur NodeJs avec votre application Sails.js. commande.PNG Voici la page d'accueil dans votre navigateur quand vous tapez l'adresse suivante : http://localhost:1337 index.PNG

Petit tour du propriétaire

Voici la structure de votre nouveau projet arbo_sails

  • api : toutes les couches de votre logique métier (le modèle, les contrôleurs, les services ...)
  • assets : le dossier pour les fichiers JS et les CSS
  • config : contient tous les fichiers de configuration liés à l'application (les adaptateurs pour les bases de données, les configurations globals pour : les rôles utilisateurs, les contrôleurs, les vues,...)
  • node_modules : modules NodeJs utilisés au sein du projet
  • views : templates Javascript au format EJS
  • app.js : fichier exécuter au lancement de votre application
  • Gruntfile.js : définitions des tâches Grunt par défaut (minification, injection automatique des CSS et JS dans les vues...)
  • package.json : déclare les dépendances Node de l'application, les informations propres à l'application (version, description, fichier principal...)

Développons une gestion d'utilisateurs

Sails.js permet très simplement et rapidement de créer un service REST avec le modèle et le contrôleur associés. Exécutez cette commande à la racine de votre projet

 sails generate model User

(NB : A chaque fois que vous créez, modifiez ou supprimez un fichier il faut redémarrer le serveur) Faisons un test dans un navigateur

 http://localhost:1337/user

user1.PNG Nous avons un super flux de retour vide car nous n'avons aucun utilisateur.

Maintenant si vous allez dans le dossier /api/models vous aurez un fichier User.js de même que dans le dossier /api/controllers vous aurez le fichier UserController.js

Le modèle

Si on ouvre le fichier User.js on a ceci

 /**  * User  *  * @module      :: Model  * @description :: A short summary of how this model works and what it represents.  * @docs		:: http://sailsjs.org/#!documentation/models  */ module.exports = {   attributes: {   	/* e.g.   	nickname: 'string'   	*/   } };

En gros une coquille vide. Nous allons ajouter des attributs à notre objet. Vous trouverez dans la documentation toutes les types supportés ainsi que les options de validation.

 module.exports = {   attributes: {     firstName: 'STRING',     lastName: 'STRING',     age: {       type: 'INTEGER'     },     birthDate: 'DATE',     phoneNumber: {       type: 'STRING'     },     emailAddress: {       type: 'STRING'     },     pseudo: {     type: 'STRING'   	}   } };

Vous remarquerez que vous avez 2 façons de déclarer une propriété, soit comme un objet, soit directement comme une propriété avec pour valeur le type associé. Maintenant nous allons alimenter notre base d'utilisateurs, pour cela je vous conseille un client sous Chrome tel que Postman

Ajoutons un utilisateur

createUser.PNG Au retour nous avons notre nouvel objet avec son identifiant createResult1.PNG et si nous rappelons le service REST pour lister les utilisateurs, http://localhost:1337/user nous avons ce retour

 [   {     "firstName": "henry",     "lastName": "leconte",     "age": 50,     "birthDate": "01/01/1964",     "phoneNumber": "",     "emailAddress": "henrylecomte@mail.com",     "pseudo": "",     "createdAt": "2014-06-05T11:21:23.513Z",     "updatedAt": "2014-06-05T11:21:23.513Z",     "id": 4   } ]

Par défaut Sails.js stocke les données du modèle dans un fichier disk.db, ce qui correspond à l'adaptateur sails-disk, que vous retrouvez dans le répertoire .tmp à la racine de votre projet. Si l'on veut changer le type de stockage pour passer par exemple sous une base de données MongoDB ou "MySQL" il faut installer l'adaptateur correspondant via les commandes suivantes (à exécuter à la racine de votre projet) :

 npm install sails-mongo npm install sails-mysql

puis il faut configurer vos adaptateurs pour qu'ils puissent se connecter à votre base de donnée. Pour cela il faut configurer le fichier /config/adpaters.js. Comme vous pouvez le voir par défaut c'est d'adaptateur 'disk' qui est utilisé, et vous pouvez ajouter autant de définition d'adaptateur que vous le souhaitez du moment que vous avez installé le module NodeJS correspondant.

La validation

On va un peu changer notre définition du modèle pour contrôler la saisie

 module.exports = {   attributes: {     firstName: 'STRING',     lastName: 'STRING',     age: {       type: 'INTEGER',       max: 150,       required: true     },     birthDate: 'DATE',     phoneNumber: {       type: 'STRING',       defaultsTo: '111-222-3333'     },     emailAddress: {       type: 'email',       required: true     },     pseudo: {     type: 'string',     maxLength: 20,     minLength: 5   	}   } };

(NB : n'oubliez pas de redémarrer votre serveur ;))

Si on test avec des données erronées : createErreur.PNG

Le contrôleur

Jusqu'ici nous n'avons qu'utilisé que les méthodes par défaut générées à la création de notre objet modèle. Nous allons enrichir notre contrôleur et voir quelques possibilités de l'ORM Waterline. Ouvrez le fichier /api/controllers/UserContollers.js. Pour l'instant il ressemble à ceci

 module.exports = {   /**    * Overrides for the settings in `config/controllers.js`    * (specific to UserController)    */   _config: {} };

Nous allons ajouter 2 nouvelles méthodes, une pour rechercher les utilisateurs par leur pseudo et une autre pour retrouver les utilisateurs majeurs.

Recherche par pseudo
 findByPseudo: function (req, res) {     sails.log.debug("*******************findByPseudo");     User.findOneByPseudo(req.body.pseudo).done(function (err, user) {       if (err) res.json({ error: 'oups error' }, 500);       if (user) {           res.json(user)       } else {         res.json({ message: 'User not found' });       }     });   }

Ici nous utilisons une possibilité de Waterline, le dynamic finder qui permet de faire une recherche sur une propriété du modèle directement via le nom de la méthode. C'est à dire que dans notre cas si on décompose le nom de la méthode findOneByPseudo on indique à Waterline que l'on recherche un User dont le pseudo est également à la valeur passée en paramètre. Ensuite dans le corps de la méthode vous implémentez votre logique. Pour appeler cette méthode vous avez juste besoin de faire l'appel : byPsuedo.PNG

Recherche des utilisateurs majeurs

 findAdult: function (req, res) {     sails.log.debug("*******************finAdult");     User.find({ 		  age: { 		    '>=': 18 		  } 	}).done(function (err, users) {       if (err) res.json({ error: 'oups error' }, 500);       if (users) {           res.json(users)       } else {         res.json({ message: 'User not found' });       }     });   }

Pour faire notre recherche d'utilisateurs majeurs, nous utilisons des conditions sur les propriétés du modèle, en l’occurrence l'âge de nos utilisateurs. getAdult.PNG

Pour plus détails sur les possibilités de Warterline sur la recherche vous avez la documentation de et celle de Waterline

Nouvelle version bêta

Avant de conclue un petit mot sur la version actuellement en bêta, la v0.10.0, que vous pouvez utiliser en utilisant la commande

 npm install sails@beta

Et dont la documentation est disponible à cette adresse beta. Dans les fonctionnalités intéressantes on peut noter :

  • l'utilisation de la dernière version de Waterline qui permet notamment de faire de la relation entre les objets de votre modèle, ce qui est un vrai manque dans la version actuelle.
  • un nouveau système d'upload de fichiers par streaming
  • la possibilité d'émettre de événements directement en relation avec vos objets du modèle
  • de nouvelles commandes dans le générateur Sails.js pour par exemple créer un site de blog avec une architecture directement opérationnelle en Sails.js

Conclusion

Ce framework est très riche en fonctionnalités et par ce post je n'ai présenté que des éléments de bases, sans aborder la partie vue avec les templates, la gestion des rôles utilisateurs, la communication temps réelle, les commandes en pré et post exécution des commandes sur le modèle et bien d'autres fonctionnalités disponibles dans la version release et celles qui seront apportées par la version en bêta. Sails.js est simple d'utilisation, rapide à prendre en main, il a un bon accueil sur le net, je vous encourage donc à faire un tour avec Sails.js.

Références

site officiel Sails.js

git hub du projet Sails.js

git hub du projet Waterline

Screencast

introduction à Sails

créer une application from scratch

8 commentaires

  1. « sails generate model User » ne génère que le modèle pour générer les 2 il faudrait mettre dans le tutorial « sails generate User » non ?

  2. La méthode done utilisée dans le controlleur est aujourd’hui dépréciée et ne marchait pas avec ma version. A la place il a fallu que j’utilise exec.

  3. Désolé je n’avais pas vu plus tôt les commentaires. Quand j’ai écrit ce post la version release de SailsJS était 0.9.16, la version 0.10 était en bêta. Quand tu as fait ton test tu étais minimun en 0.10 voir en 0.11 puisqu’il y avait les RC. Ceci explique les différences que tu as pu constater.

  4. J’ai essayé, pour moi le « sails generate User » ne marche plus, il fallait ajouter api : « sails generate api user »

  5. Merci pour ce post en langue française car ils sont rares. En effet, sails semble etre promu a un bel avenir pour tous les passionnées de nodejs.

  6. Je suis en train de refaire le tutoriel et je retombe sur les mêmes erreurs. C’est dommage de ne pas avoir corrigé la méthode « done ».

  7. Je n’ai plus la main sur le contenu du post, je ne peux malheureusement pas faire de modification de son contenu.
    Je ferai un nouveau post avec la version 0.12 de Sails ce qui permettra de parler des nouveautés du framework.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.