Afin de conclure la série d’articles sur les API, je vous propose ici d’aborder un élément essentiel dans leur développement : le système de gestion de base de données (SGBD). Pour ce faire, nous allons reprendre le développement réalisé précédemment dans l’article intitulé : Développez votre propre API avec Node.js et Express, dans lequel je vous avais proposé un exemple d’API répertoriant les piscines de la métropole lilloise. Je vous invite donc à vous y référer car nous allons ici finaliser cette API en proposant un SGBD NoSQL : MongoDB.

MongoDB, un SGBD NoSQL

MongoDB est un système de gestion de base de données NoSQL (orienté document) en opposition avec les SGBD relationnels SQL traditionnels. Je ne m’attarderai pas sur la distinction entre les SGBD SQL et NoSQL, de nombreuses ressources sont disponibles à ce sujet. Retenez juste qu’à la différence des systèmes SQL qui reposent sur des tables relationnelles, MongoDB repose sur des collections de documents au format JSON (clé/valeur).

Pour nous plonger sans plus attendre dans l’application qui nous intéresse, vous trouverez ci-dessous l’exemple d’une collection contenant deux documents. Chaque document représente une piscine.

Exemple d’une collection contenant deux documents

Afin de faciliter l’accès et les différentes opérations liées à la base MongoDB, nous allons utiliser un framework nommé Mongoose. Pour installer ce framework, rien de plus simple, il suffit d’entrer la commande (dans votre console) depuis le dossier restfrugal* :

npm install mongoose --save

*A ce stade, vous devriez avoir en héritage de l’article précédent, un dossier nommé restfrugal dans lequel se trouve le fichier apifrugal.js, contenant la logique de notre API.

Par souci de simplicité, nous utiliserons dans cet article une base MongoDB hébergée gratuitement, dans la limite de 500MB, chez mLab. Ce qui est largement suffisant dans notre cas et cela nous évite d’installer MongoDB sur notre poste. Si vous souhaitez tout de même l’installer sur votre poste, de nombreuses ressources sont disponibles sur le web.

Inscrivez-vous sur le site et créer une nouvelle base (choisir create new, ensuite cliquer sur single node et choisir Sandbox : FREE). Enfin, nommez la base ; nous la nommerons restfrugaldb (tout en minuscule) dans notre cas. Voilà, notre base de données à été créée. Dernière petite chose avant de pouvoir y accéder, nous devons créer un utilisateur. C’est dans la rubrique Users que cela se passe. Cliquez alors sur Add database user et entrez les informations demandées. Vous pouvez utiliser celle que j’ai créée pour ce tutoriel (userfrugal:passwordfrugal). Une fois cela fait, nous pourrons accéder à notre base de données via le lien suivant :

mongodb://userfrugal:passwordfrugal@ds151108.mlab.com:51108/restfrugaldb

Utilisation de Mongoose dans notre API

 Reprenons le fichier apifrugal.js contenant la logique de notre API. Nous allons y ajouter quelques lignes de codes pour indiquer que nous allons utiliser le framework mongoose et inscrire l’adresse de notre base de données. Ensuite nous établissons la connexion avec la base.

//L'application requiert l'utilisation du module Express.
//La variable express nous permettra d'utiliser les fonctionnalités du module Express.  
var express = require('express');

// Nous définissons ici les paramètres du serveur.
var hostname = 'localhost'; 
var port = 3000; 

// La variable mongoose nous permettra d'utiliser les fonctionnalités du module mongoose.
var mongoose = require('mongoose'); 
// Ces options sont recommandées par mLab pour une connexion à la base
var options = { server: { socketOptions: { keepAlive: 300000, connectTimeoutMS: 30000 } }, 
replset: { socketOptions: { keepAlive: 300000, connectTimeoutMS : 30000 } } };

//URL de notre base
var urlmongo = "mongodb://userfrugal:passwordfrugal@ds151108.mlab.com:51108/restfrugaldb"; 

// Nous connectons l'API à notre base de données
mongoose.connect(urlmongo, options);

var db = mongoose.connection; 
db.on('error', console.error.bind(console, 'Erreur lors de la connexion')); 
db.once('open', function (){
    console.log("Connexion à la base OK"); 
}); 
 
// Nous créons un objet de type Express. 
var app = express(); 

var bodyParser = require("body-parser"); 
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());


Maintenant que nous nous sommes connectés à la base, nous allons implémenter chacune des méthodes (GET, POST, PUT, DELETE) de notre API. Avant cela, nous devons définir un schéma pour nos données. En effet, mongoose utilise des schémas pour modéliser les données.

// CODE
// Pour modéliser les données, le framework mongoose utilise des "schémas" ; nous créons donc un modèle de données :
var piscineSchema = mongoose.Schema({
    nom: String, 
    adresse: String, 
    tel: String, 
    description: String   
}); 

var Piscine = mongoose.model('Piscine', piscineSchema);
//SUITE DU CODE

Nous allons ensuite utiliser ce schéma dans chacune des méthodes de notre API. Commençons par le plus simple : la méthode GET. Il s’agit dans ce cas d’interroger la base et de renvoyer à l’utilisateur la liste de toutes les piscines.

// Je vous rappelle notre route (/piscines).  
myRouter.route('/piscines')
// J'implémente les méthodes GET, PUT, UPDATE et DELETE
// GET
.get(function(req,res){ 
// Utilisation de notre schéma Piscine pour interrogation de la base
    Piscine.find(function(err, piscines){
        if (err){
            res.send(err); 
        }
        res.json(piscines); 
        
    }; 
}) // SUITE DU CODE

Si aucune piscine n’est inscrite en base (ce qui devrait être le cas avec une base fraichement créée), la méthode GET devrait renvoyer un tableau vide. Voyons maintenant comment ajouter des piscines à notre base de données. Nous allons tenir compte de notre schéma Piscine pour fournir les informations attendues par la base. Nous avions vu dans l’article précédent comment récupérer les données envoyées par la méthode POST, c’est exactement ce que nous allons faire ici.

.post(function(req,res){
    // Nous utilisons le schéma Piscine
      var piscine = new Piscine();
    // Nous récupérons les données reçues pour les ajouter à l'objet Piscine
      piscine.nom = req.body.nom;
      piscine.adresse = req.body.adresse;
      piscine.tel = req.body.tel;
      piscine.description = req.body.description; 
    //Nous stockons l'objet en base
      piscine.save(function(err){
        if(err){
          res.send(err);
        }
        res.send({message : 'Bravo, la piscine est maintenant stockée en base de données'});
      })
})

Vous pouvez maintenant ajouter des piscines avec l’application Postman comme illustré ci-dessous :

Ajout d’une piscine avec l’application Postman

Vous avez compris le principe. Pour le reste des méthodes, en particulier pour la méthode PUT, les opérations se feront sur une piscine que nous aurons identifiée par son identifiant dans l’URI. Encore une fois, je vous invite à vous référer à l’article sur le sujet, si tout cela n’est pas très clair. Ci-dessous les méthodes GET, PUT et DELETE pour une piscine identifiée.

myRouter.route('/piscines/:piscine_id')
.get(function(req,res){ 
            //Mongoose prévoit une fonction pour la recherche d'un document par son identifiant
            Piscine.findById(req.params.piscine_id, function(err, piscine) {
            if (err)
                res.send(err);
            res.json(piscine);
        });
})
.put(function(req,res){ 
    // On commence par rechercher la piscine souhaitée
                Piscine.findById(req.params.piscine_id, function(err, piscine) {
                if (err){
                    res.send(err);
                }
                    // Mise à jour des données de la piscine
                        piscine.nom = req.body.nom;
                        piscine.adresse = req.body.adresse;
                        piscine.tel = req.body.tel;
                        piscine.description = req.body.description; 
                              piscine.save(function(err){
                                if(err){
                                  res.send(err);
                                }
                                // Si tout est ok
                                res.json({message : 'Bravo, mise à jour des données OK'});
                              });                
                });
})
.delete(function(req,res){ 

    Piscine.remove({_id: req.params.piscine_id}, function(err, piscine){
        if (err){
            res.send(err); 
        }
        res.json({message:"Bravo, piscine supprimée"}); 
    }); 
    
});

Voilà ! Nous avons une API fonctionnelle. Bien entendu, nous avons simplifié beaucoup de choses dans le développement de cette API, mais c’est déjà un très bon début pour se lancer dans un prototype de service. Si des choses vous ont échappées ou si vous souhaitez approfondir certains points, n’hésitez pas à nous laisser un commentaire. Je vous laisse ci-dessous l’intégralité du fichier apifrugal.js :

var express = require('express');
var hostname = 'localhost'; 
var port = 3000; 
var mongoose = require('mongoose'); 
var options = { server: { socketOptions: { keepAlive: 300000, connectTimeoutMS: 30000 } }, 
replset: { socketOptions: { keepAlive: 300000, connectTimeoutMS : 30000 } } };
var urlmongo = "mongodb://userfrugal:passwordfrugal@ds151108.mlab.com:51108/restfrugaldb"; 
mongoose.connect(urlmongo, options);
var db = mongoose.connection; 
db.on('error', console.error.bind(console, 'Erreur lors de la connexion')); 
db.once('open', function (){
    console.log("Connexion à la base OK"); 
}); 
var app = express(); 
var bodyParser = require("body-parser"); 
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
var piscineSchema = mongoose.Schema({
    nom: String, 
    adresse: String, 
    tel: String, 
    description: String   
}); 
var Piscine = mongoose.model('Piscine', piscineSchema); 
var myRouter = express.Router(); 
myRouter.route('/')
.all(function(req,res){ 
      res.json({message : "Bienvenue sur notre Frugal API ", methode : req.method});
});
  
myRouter.route('/piscines')
.get(function(req,res){ 
	Piscine.find(function(err, piscines){
        if (err){
            res.send(err); 
        }
        res.json(piscines);  
    }); 
})
.post(function(req,res){
      var piscine = new Piscine();
      piscine.nom = req.body.nom;
      piscine.adresse = req.body.adresse;
      piscine.tel = req.body.tel;
      piscine.description = req.body.description; 
      piscine.save(function(err){
        if(err){
          res.send(err);
        }
        res.json({message : 'Bravo, la piscine est maintenant stockée en base de données'});
      }); 
}); 

myRouter.route('/piscines/:piscine_id')
.get(function(req,res){ 
            Piscine.findById(req.params.piscine_id, function(err, piscine) {
            if (err)
                res.send(err);
            res.json(piscine);
        });
})
.put(function(req,res){ 
                Piscine.findById(req.params.piscine_id, function(err, piscine) {
                if (err){
                    res.send(err);
                }
                        piscine.nom = req.body.nom;
                        piscine.adresse = req.body.adresse;
                        piscine.tel = req.body.tel;
                        piscine.description = req.body.description; 
                              piscine.save(function(err){
                                if(err){
                                  res.send(err);
                                }
                                res.json({message : 'Bravo, mise à jour des données OK'});
                              });                
                });
})
.delete(function(req,res){ 

    Piscine.remove({_id: req.params.piscine_id}, function(err, piscine){
        if (err){
            res.send(err); 
        }
        res.json({message:"Bravo, piscine supprimée"}); 
    }); 
    
});
app.use(myRouter);   
app.listen(port, hostname, function(){
	console.log("Mon serveur fonctionne sur http://"+ hostname +":"+port); 
});

Si le sujet de l’innovation citoyenne vous intéresse et que vous souhaitez contribuer à améliorer les services de votre ville par le biais de ce genre de développement, sachez que nous sommes actifs au sein d’une association qui œuvre dans ce sens : le Citizen Clan.  Et que vous êtes bien entendu les bienvenus. Ce sujet fait d’ailleurs l’objet d’un projet en cours.

Comme d’habitude, si des erreurs se sont glissées dans l’article, n’hésitez pas à nous en faire part.

Pour être informé des prochains articles, rendez-vous sur Twitter.

Merci, et à très bientôt sur Frugal Prototype

 


Ali Benfattoum

Intrapreneur, Tech Enthusiast, IoT Expert, Smart City Specialist…
Suivez moi sur @alifrugal

All author posts
Related Posts

Privacy Preference Center