web-dev-qa-db-fra.com

Création d'une application d'entreprise avec Node/Express

J'essaie de comprendre comment structurer les applications d'entreprise avec Node/Express/Mongo (en utilisant une pile MEAN). 

Après avoir lu 2 livres et des articles sur Google (y compris des questions similaires sur StackOverflow), je n’ai trouvé aucun bon exemple de structuration d’applications volumineuses à l’aide d’Express. Toutes les sources que j'ai lues suggèrent de scinder l'application par les entités suivantes: 

  • itinéraires
  • contrôleurs
  • des modèles

Mais le principal problème que je vois avec cette structure est que les contrôleurs sont comme des objets divins, ils connaissent les objets req, res, responsables de la validation et ont une logique métier incluse dans. 

D'un autre côté, les routes me paraissent trop d'ingénierie, car elles ne font que mapper des points d'extrémité (chemins) avec des méthodes de contrôleur.

J'ai un arrière-plan Scala/Java, donc j’ai l’habitude de séparer toute la logique en 3 niveaux - contrôleur/service/dao. 

Pour moi, les déclarations suivantes sont idéales: 

  • Les contrôleurs sont uniquement responsables de l’interaction avec la partie Web, c’est-à-dire le marshalling/unmarshalling, une simple validation (obligatoire, min, max, adresse regex, etc.); 

  • La couche de service (que j'ai manquée dans les applications NodeJS/Express) est uniquement responsable de la logique métier, de la validation de certaines tâches. La couche service ne connaît rien de la partie WEB (c’est-à-dire qu’elles peuvent être appelées depuis un autre lieu d’application, pas seulement depuis le contexte Web);

  • En ce qui concerne la couche DAO est tout clair pour moi. Les mannequins Mongoose sont en réalité des modèles DAO, donc ce qui est le plus clair pour moi ici.

Je pense que les exemples que j'ai vus sont très simples et qu'ils ne montrent que les concepts de Node/Express, mais je veux regarder un exemple concret, avec une grande partie de la logique/validation métier impliquée. 

MODIFIER: 

Une autre chose qui n’est pas claire pour moi est l’absence d’objets DTO. Considérons cet exemple: 

const mongoose = require('mongoose');
const Article = mongoose.model('Article');
exports.create = function(req, res) {
    // Create a new article object
    const article = new Article(req.body);
    // saving article and other code
}

Là, l'objet JSON de req.body est passé en tant que paramètre pour la création d'un document Mongo. Ça sent mauvais pour moi. J'aimerais travailler avec des cours concrets, pas avec JSON brut

Merci.

51
MyTitle

Tout le monde a sa propre manière de diviser le projet en certains dossiers . La structure que j’utilise est 

  • config
  • les journaux
  • itinéraires
  • contrôleurs
  • des modèles
  • prestations de service
  • utils
  • app.js/server.js/index.js (n'importe quel nom que vous préférez)

le dossier config contient des fichiers de configuration tels que les paramètres de connexion à la base de données pour toutes les phases de développement, tels que "production", "développement", "tests". 

exemple

'use strict'
var dbsettings = {
    "production": {
//your test settings
    },
    "test": {

    },
    "development": {
        "database": "be",
        "username": "yourname",
        "password": "yourpassword",
        "Host": "localhost",
        "connectionLimit": 100
    }
}
module.exports = dbsettings

le dossier de journalisation contient vos journaux de connexion 

le contrôleur sert à valider vos données req et votre logique métier

exemple

const service = require("../../service")
const async = require("async")
exports.techverify = (data, callback) => {

    async.series([
        (cb) => {
            let searchObject = { accessToken: data.accessToken }
            service.admin.get(searchObject, (err, result) => {
                if (err || result.length == 0) {
                    callback(err, { message: "accessToken is invalid" })
                } else {
                    delete data.accessToken
                    service.tech.update(data, { verified: true }, (err, affe, res) => {
                        if (!err)
                            callback(err, { message: "verification done" })
                        else
                            callback(err, { message: "error occured" })
                    })
                }
            })
        }
    ])
}

modèles est pour définir votre schéma de base de données

exemple de schéma mongoDb 

'use strict'
let mongoose = require('mongoose');
let schema = mongoose.Schema;
let user = new schema({
    accesstoken: { type: String },
    firstname: { type: String },
    lastname: { type: String },
    email: { type: String, unique: true },
    image: { type: String },
    phoneNo: { type: String },
    gender: { type: String },
    deviceType: { type: String },
    password: { type: String },
    regAddress: { type: String },
    pincode: { type: String },
    fbId: { type: String, default: 0 },
    created_at: { type: Date, default: Date.now },
    updated_at: { type: Date, default: Date.now },
    one_time_password: { type: String },
    forgot_password_token: { type: String },
    is_block: { type: Boolean, default: 0 },
    skin_type: { type: String },
    hair_length: { type: String },
    hair_type: { type: String },
    credits: { type: Number, default: 0 },
    invite_code: { type: String },
    refered_by: { type: String },
    card_details: [{
        card_type: { type: String },
        card_no: { type: String },
        card_cv_no: { type: String },
        created_at: { type: Date }
    }]
});
module.exports = mongoose.model('user', user);

services est destiné à l'écriture de votre requête de base de données évitez d'écrire des requêtes dans le contrôleur essayez d'écrire une requête dans ce dossier et appelez-le dans le contrôleur

requêtes utilisant la mangouste

'use strict'
const modelUser = require('../../models/user');
exports.insert = (data, callback) => {
    console.log('mongo log for insert function', data)
    new modelUser(data).save(callback)
}
exports.get = (data, callback) => {
    console.log('mongo log for get function', data)
    modelUser.find(data, callback)
}
exports.update = (data, updateData, callback) => {
    console.log('mongo log for update function', data)
    modelUser.update(data, updateData, callback);
}
exports.getWithProjection = (data, projection, callback) => {
    console.log('mongo log for get function', data)
    modelUser.find(data, projection, callback)
}

utils est une fonction d’utilité commune qui est couramment utilisée dans votre projet, par exemple, comme chiffrer, déchiffrer le mot de passe, etc. 

exemple

exports.checkPassword = (text, psypherText) => {
    console.log("checkPassword executed")
    console.log(text, psypherText)
    return bcrypt.compareSync(text, psypherText)
}
exports.generateToken = (userEmail) => {
    return jwt.sign({ unique: userEmail, timeStamp: Date.now }, config.keys.jsonwebtoken)
}
4
rohit salaria

règle simple et fondamentale

  1. Gardez les composants associés proches les uns des autres.

  2. Diviser la page en composants et travail

  3. Tous les composants dépendants doivent être ensemble

  4. les objets partagés doivent rester indépendants de tous les autres composants.

Enfin chaque langue est douce. C'est juste que vous êtes familier avec la langue. Vous ne pouvez gagner la bataille que si vous connaissez votre épée.

je développe l'application Angular2 à l'aide de NodeJS, Angular2, je vais vous aider avec la structure de mon répertoire.

 main Module

`le module principal` 

 subModule

  `la structure du sous-module`

 shared Module

`garder le dossier partagé en tant que module séparé`

J'espère que ça aide :)

0
manish kumar

la réponse de rohit salaria explique essentiellement la même structure d'application que celle utilisée en Java.

  • Les contrôleurs sont les contrôleurs en Java
  • Les modèles sont la couche d'accès aux données
  • Les services sont la couche de service

J'ai quelques remarques cependant. Le premier et le plus important est qu'il ne s'agit pas de Java. Cela peut sembler évident, mais examinez simplement votre question et constatez que vous visez la même expérience de développement avec les mêmes concepts que ceux que vous avez utilisés dans le monde Java. Mes remarques suivantes ne sont que l'explication de cela.

DTO manquants. En Java, ils sont juste nécessaires, point final. Dans une application Web Java, où vous stockez vos données dans une base de données relationnelle et envoyez et recevez des données au serveur frontal en JSON, il est naturel que vous convertissiez les données en un objet Java. Cependant, dans une application Node, tout est javascript et JSON. C'est l'un des points forts de la plateforme. JSON étant le format de données commun, il n'est pas nécessaire d'écrire du code ni de dépendre de bibliothèques pour convertir le format de données de vos couches.

Passer l'objet de données directement de la demande au modèle. Pourquoi pas? L'utilisation du format JSON comme format de données commun du serveur frontal à la base de données vous permet de synchroniser facilement le modèle de données de votre application entre toutes vos couches. Bien sûr, vous n'êtes pas obligé de suivre cette voie, mais c'est suffisant la plupart du temps, alors pourquoi ne pas l'utiliser? Quant à la validation, elle est effectuée dans le modèle, où elle appartient conformément à la théorie MVC (et non dans le contrôleur où la paresse et le pragmatisme le disent souvent :)).

Pour la pensée finale que je veux ajouter, il ne s’agit pas de la meilleure plate-forme pour l’échelle de la taille du projet. Nod bat du tout, mais Java est meilleur dans cet aspect. 

0
Imperator