web-dev-qa-db-fra.com

Comment créer au mieux une API RESTful dans Node.js

Je suis un débutant dans Node (et généralement tout le développement Web back-end) et j'ai commencé à écrire une API RESTful dans Node. Il y a quelques points que j'essaie de comprendre.

Mon application utilise Express et Mongoose et j'utilise le module express-resource pour créer facilement mes routes CRUD pour les ressources de l'API. Mais il y a quelques choses qui me déplaisent et je pense que je pourrais faire mieux.

Le premier est Mongoose. Si je veux écrire des tests pour mon API, je ne dispose d'aucun moyen d'empêcher Mongoose de le forcer dans les données en mémoire. Tous les didacticiels semblent indiquer Mongoose, cependant, et je ne suis vraiment pas sûr de ce que je devrais utiliser.

Deuxièmement, ma ressource semble avoir beaucoup de code standard. Est-ce vraiment le meilleur moyen de créer une API RESTful dans Node.js? Existe-t-il d'autres modules qui m'aideront à créer mes itinéraires CRUD? Je pense qu'il existe des moyens de créer des routes CRUD directement à partir de votre schéma, sans plus de code, mais je ne sais vraiment pas comment.

J'ai vu des projets tels que Tower.js et CompoundJS (anciennement RailwayJS) qui semblent être ces solutions complètes qui résolvent beaucoup plus que mes problèmes ici. Je devrais peut-être les utiliser, mais je veux vraiment que l'application Node.js soit une API et rien de plus. Je traite avec le front-end indépendamment de l'API.

Pour vous donner un peu de contexte, voici ma situation actuelle. Actuellement, j'ai un modèle défini dans Mongoose:

var mongoose = require('mongoose')
  , Schema = mongoose.Schema
  , Link

var LinkSchema = new Schema({
  uri: String,
  meta: {
    title: String,
    desc: String
  },
  shares: [{
    uid: Schema.Types.ObjectId,
    date: Date,
    message: String
  }]
})

Link = module.exports = mongoose.model('Link')

Ensuite, je définis les contrôleurs pour les routes CRUD:

var mongoose = require('mongoose')
  , _ = require('underscore')
  , Link = mongoose.model('Link')

exports.load = function (req, id, fn) {
  Link.findById(req.params.link, function (err, link) {
    if (err) {
      return res.send(err)
    }

    fn(null, link)
  })
}

exports.index = function (req, res) {
  var filterByUser = req.query.user ? { 'shares.uid': req.query.user } : {}

  Link.find(filterByUser, function (err, links) {
    if (err) {
      return res.send(err)
    }

    res.send(links)
  })
}

exports.create = function (req, res) {
  var link = new Link(req.body)

  link.save(function (err) {
    if (err) {
      // TODO: send 404
      return res.send(err)
    }

    res.send(link)
  })
}

exports.show = function (req, res) {
  res.send(req.link)
}

exports.update = function (req, res) {
  req.link = _(req.link).extend(req.body)

  req.link.save(function (err, link) {
    if (err) {
      return res.send(err)
    }

    res.send(link)
  })
}

exports.patch = exports.update

exports.destroy = function (req, res) {
  req.link.remove(function (err) {
    if (err) {
      return res.send(err)
    }

    res.send()
  })
}

Enfin, j'utilise le module express-resource pour mapper ces contrôleurs sur les routes CRUD nécessaires au-dessus de l'application Express.

app.resource('api/links', require('../resources/links'))
45
user1082754

Vous devriez regarder dans restify

Si vous souhaitez utiliser express, vous pouvez également consulter ce projet que j'ai réalisé - appelé node-reposful .

Cette bibliothèque semble être beaucoup plus mature et avoir plus de fonctionnalités que: https://github.com/jspears/mers

29
Benoir

Strongloop Loopback semble être une autre bonne alternative pour générer des API Node/MongoDB. Il peut également générer tests mocha aussi.

5
Sean McClory

Jetez un coup d’œil à Hapi c’est un framework centré sur la configuration pour la construction d’API et d’applications Web qui est utilisé comme service reposant.

Les autres options sont sails.js et actionhero

4
ramon22

Strapi est un nouveau cadre (2015).

L'interface d'administration de leur site Web vous permet de créer une API et de spécifier les relations entre les modèles. (Comme on peut le voir dans leur vidéo d'introduction.)

Cependant, il est conçu pour fonctionner sur le serveur Koa, pas sur Express.

4
joeytwiddle

Voici les problèmes concernant les frameworks de nos jours.

Quand vous venez ici de google, recherchez "meilleur", "le plus rapide" framework blah, blah, les gens vont laisser tomber une ligne dit "Hey, vous devriez essayer ceci sails.js, plumes, Derby etc ..." 

Ok La question est la suivante: - Vous vous contentez de vous amuser avec ces frameworks - si oui, vous pouvez facilement obtenir une liste des frameworks et ensuite commencer à les comparer quels qu'ils soient.

  • Je suppose que la plupart des gens disent: "Je veux construire un produit, créer un site peut rapporter de l'argent dans le futur, ou du moins il deviendra populaire"; 

Ok, tous vos mots-clés et toutes vos attentions ici sont faux, essayez alors de rechercher "prêt à la production", "entreprise prête", "étude de cas" puis ces mots-clés, ou peut-être aller à Indeed.com et à la recherche node.js, puis creuser Comme la plupart des entreprises utilisent le framework node.js, la réponse peut-être simplement dire "express".

si c'est le cas, à partir de la pile de noeuds.js, les frameworks seront plus ou moins restreints: Hapi, Strongloop, ou même pas populaires Mojito de Yahoo

Pour ces frameworks au moins, vous pouvez dire - "Ils sont vraiment prêts pour la production ou l'entreprise" - parce qu'ils utilisent Walmart, de Yahoo, d'autres grands géants depuis un certain temps, certains depuis quelques années.

Est-ce que cela peut expliquer pourquoi Ruby on Rails et Django dominent toujours les marchés du framework complet? Même si vous voyez beaucoup de frameworks "sympas" qui arrivent sans cesse sur le marché, Meteor, Sails.js, Go's Revel, Java's Play Spark comme vous pouvez le nommer - Cela ne veut pas dire que ces frameworks sont pires que les deux, mais qu'ils ont besoin de temps gagner le marché.

Un autre problème est que beaucoup des frameworks actuels sont une sorte de tout-en-un, clone de "Ror"; Du point de vue de l'utilisateur final, ils ont juste besoin de quelque chose pour les aider à accomplir leurs tâches, ont besoin de quelque chose à travailler du début à la fin, comme Ruby on Rails, comme MacOS, comme Windows, comme tout ce qui a été testé à l'époque, a été utilisé quotidiennement par les gens. 

2
elawcn

Je recommande Baucis + Express. Des milliers d'utilisateurs, conception basée sur le modèle basée sur Mongoose, très flexible, conforme aux spécifications, compatible HATEOAS/Level 3. Convient parfaitement à tous mes besoins. Mais alors, je suis l'auteur :) https://github.com/wprl/baucis

2
wprl

Regarde ça:  enter image description here

Avec Feathers, vous pouvez créer des prototypes en quelques minutes et des backends temps réel prêts pour la production et des API REST en quelques jours. Sérieusement.

2
yokodev

Essayez https://hivepod.io/ et générez votre exemple dans une pile MEAN complète. Hivepod repose sur BaucisJS + ExpressJS + MongoDB + AngularJS.

Disclaimer: Je travaille à la construction de Hivepod.

0
pjmolina
    var mongoose        = require('../DBSchema/SchemaMapper');
    var UserSchema      = mongoose.model('User');

    var UserController = function(){
        this.insert = (data) => {
            return new Promise((resolve, reject) => {
                var user = new UserSchema({
                    userName: data.userName,
                    password: data.password
                });
                user.save().then(() => {
                    resolve({status: 200, message: "Added new user"});
                }).catch(err => {
                    reject({status: 500, message: "Error:- "+err});
                })
            })

        }

        this.update = (id, data) => {
            return new Promise((resolve, reject) => {
                UserSchema.update({_id: id}, data).then(() => {
                    resolve({status: 200, message: "update user"});
                }).catch(err => {
                    reject({status: 500, message: "Error:- " + err});
                })
            })
        }

        this.searchAll = () => {
            return new Promise((resolve, reject) => {
                UserSchema.find().exec().then((data) => {
                    resolve({status: 200, data: data});
                }).catch(err => {
                    reject({status: 500, message: "Error:- " + err});
                })
            })
        }

        this.search = (id) => {
            return new Promise((resolve, reject) => {
                UserSchema.find({_id:id}).exec().then(user => {
                    resolve({status: 200, data: user});
                }).catch(err => {
                    reject({status: 500, message: "Error:- " + err});
                })
            })
        }

        this.delete = (id) => {
            return new Promise((resolve, reject) => {
                UserSchema.remove({_id:id}).then(() => {
                    resolve({status: 200, message: "remove user"});
                }).catch(err => {
                    reject({status: 500, message:"Error:- " + err});
                })
            })
        }
    }

    module.exports = new UserController();

    ///Route
    var express     = require('express');
    var router      = express.Router();
    var Controller  = require('./User.Controller');



    router.post('/', (req, res) => {
        Controller.insert(req.body).then(data => {
            res.status(data.status).send({message: data.message});
        }).catch(err => {
            res.status(err.status).send({message: err.message});
        })
    });

    router.put('/:id', (req, res) => {
        Controller.update(req.params.id, req.body).then(data => {
            res.status(data.status).send({message: data.message});
        }).catch(err => {
            res.status(err.status).send({message: err.message});
        })
    });

    router.get('/', (req, res) => {
        Controller.searchAll().then(data => {
            res.status(data.status).send({data: data.data});
        }).catch(err => {
            res.status(err.status).send({message: err.message});
        });
    });

    router.get('/:id', (req, res) => {
        Controller.search(req.params.id).then(data => {
            res.status(data.status).send({data: data.data});
        }).catch(err => {
            res.status(err.status).send({message: err.message});
        });
    });

    router.delete('/:id', (req, res) => {
        Controller.delete(req.params.id).then(data => {
            res.status(data.status).send({message: data.message});
        }).catch(err => {
            res.status(err.status).send({message: err.message});
        })
    })

    module.exports = router;

//db`enter code here`schema

var mongoose = require('mongoose');
const Schema = mongoose.Schema;

var Supplier =new Schema({

    itemId:{
        type:String,
        required:true
    },
    brand:{
        type:String,
        required:true
    },
    pno:{
        type:String,
        required:true
    },   
    email:{
        type:String,
        required:true
    }    

});

mongoose.model('Inventory',Inventory);
mongoose.model('Supplier',Supplier);

mongoose.connect('mongodb://127.0.0.1:27017/LAB', function (err) {
    if (err) {
        console.log(err);
        process.exit(-1);
    }
    console.log("Connected to the db");
});
module.exports = mongoose;
0
Thilina Imalka

Ceci est un exemple pour effectuer des opérations CRUD dans un système de bibliothèque

var schema=require('../dbSchema');
var bookmodel=schema.model('book');

exports.getBooks = function (req,res) {
    bookmodel.find().exec().then((data)=>{
        res.send(data)
    }).catch((err)=>{
        console.log(err);
    });
};

exports.getBook = function (req,res) {
var bkName=req.params.Author;
bookmodel.find({Name:bkName}).exec().then((data)=>{
    res.send(data)
}).catch((err)=>{
    console.log(err);
});
};

exports.getAutBooks = function (req,res) {
    bookmodel.find({},'Author').then((data)=>{
        res.send(data);
    }).catch((err)=>{
    console.log(err);
    });
};

exports.deleteBooks=function(req,res){
    var bkName=req.params.name;
    bookmodel.remove({Name:bkName}).exec().then((data)=>{
        res.status(200);
        console.log(bkName);
    }).catch((err)=>{
        console.log(err);
    });
    };

exports.addBooks=function(req,res){
    var newBook=new bookmodel({
        Name:req.body.Name,
       ISBN:req.body.ISBN,
       Author:req.body.Author,
       Price:req.body.Price,
       Year:req.body.Year,
       Publisher:req.body.Publisher
    });
    newBook.save().then(()=>{
        res.status(201);
    }).catch((err)=>{
        console.log(err);
    });
};
0
Ashane.E

J'utilise Express pour créer mes API RESTful sur Node.js et avec l'ajout de Router dans Express 4, il est encore plus facile de le structurer. C'est détaillé ici http://www.codekitchen.ca/guide-to-structuring-and-building-a-restful-api-using-express-4/

0
Tolga E

Jetez un coup d'oeil à ceci link

Ce projet est construit en utilisant la même architecture de projet, suivie par ASP.Net WebApi 2.0. Cela signifie qu’il y aura tout d’abord des contrôleurs, un mécanisme d’authentification, etc. Tout ce que vous avez à faire est de créer vos propres contrôleurs.

0
Rahul Pal

Je suis un grand fan d’express et je l’utilise pour créer des API RESTful sur Node.js, qui sont plus faciles à créer. Cependant, lorsque notre application a commencé à prendre de l'ampleur, nous nous sommes retrouvés dans une situation où la structure expresse ne fonctionnait pas bien et avec plus de scission du code, il était plus difficile à maintenir.

Je viens d'un arrière-plan C #/Java où les principes SOLID sont fortement utilisés. Des frameworks tels que Java Spring / C# WebAPI permettent de créer des applications d'entreprise. Je souhaitais avoir un framework dans lequel je puisse réutiliser mes compétences C #/Java existantes (reuse I mean MVC architecture, OOPS, SOLID, DI, Mocks ... yeah, strong typing). Malheureusement, je n'ai pas trouvé de framework répondant à mes exigences (It should have less learning curve, minimalist codebase size, completely express compatible).

Qu'est-ce que je veux dire par complètement express compatible? Quel que soit le type d’express, je dois pouvoir le faire même si j’utilise un cadre au-dessus de celui-ci, après avoir jeté un œil sur Strongloop Loopback c’était plutôt bon à utiliser mais il y avait beaucoup de documentation à travers et les cadres sont couplés, pas vraiment ce que je cherchais.

J'ai donc créé Dinoloop powered by TypeScript (has interfaces, classes, abstract classes and strong oops). Le paquet est assez stable maintenant.

Avec Dinoloop, vous pouvez créer des applications de niveau entreprise dans une architecture évolutive . Il utilise le framework Dependency Injection, mais vous pouvez configurer tous les frameworks DI disponibles dans TypeScript. Dinoloop permet à TypeScript de s’utiliser en tant que framework Nodejs REST qui m’a aidée à maintenir une base de code TypeScript commune aux projets angular et node.

Dinoloop convient donc parfaitement aux amoureux de TypeScript et aux développeurs angulaires.

0
user3205479

Je suis surpris que personne n'ait mentionné Nodal .

Sur le site:

Nodal est un serveur Web pour Node.js, optimisé pour la création rapide et efficace de services d'API.

Bénéficiant de son propre cadre d'opinion, explicite, idiomatique et hautement extensible, Nodal prend en charge toutes les décisions difficiles pour vous et votre équipe. Cela vous permet de vous concentrer sur la création d'un produit efficace dans un délai court, tout en minimisant votre dette technique.

Il est activement mis à jour, compte plus de 3 800 étoiles sur Github (au moment de la rédaction), est doté d'un outil de ligne de commande intégré permettant de générer du code passe-partout et permet globalement de faire le travail rapidement.

0
amaurymartiny