sql >> Database teknologi >  >> NoSQL >> MongoDB

Ønsker at blive krystalklar omkring NodeJS app-struktur (Fuld JavaScript Stack)

Okay, dette er et ret bredt spørgsmål, og jeg er bestemt ingen ekspert, men jeg vil gøre mit bedste her.

TL;DR

  • routes er controllere, der fortæller, hvilken logik der skal udføres, når en bruger navigerer i deres browser til en bestemt sti i din app, herunder hvilke visninger der skal gengives, og hvilke data der skal sendes til disse visninger
  • models er netop det - datamodeller i din applikation
  • module.exports = fortæller en fil, hvad den nøjagtigt "eksporterer", det er den kode, der skal udføres eller tilgængelig fra din hovedapp-fil.
  • require(..) indeholder et modul. Du kan indstille dette på en variabel, så du kan kalde modulfunktioner senere, eller blot udføre en funktion, hvis det er alt, hvad der module.exports vender tilbage.

En kombination af disse teknikker kan hjælpe dig med at finde en solid ramme for enhver af dine applikationer.

Langt svar

Express giver en solid ramme til at strukturere din Node.js-applikation. Node er fuldstændig uafhængig af Express, men på grund af hvor populær Express er, går de praktisk talt hånd i hånd. Når det er installeret, kan Express bruges til at generere et stilladswebprojekt (med muligheder), som du kan bygge ovenpå, hvis du ønsker det.

Kontrollere

Et genereret projekt vil skabe /routes/index.js , som (hvis du forstår MVC) i bund og grund er din vigtigste controller . En rute i ekspres skrives således:

app.get('/path', function(req, res, next){ .. } );
 

Lad os bryde det ned:vores applikationsvariabel (app) får at vide det på en GET-anmodning til '/path' for at udføre en anonym tilbagekaldsfunktion med req, res, next variabler (henholdsvis anmodning, svar, tilbagekald). Jeg finder det nyttigt at tænke på dette som en tilpasset hændelseshandler.

Det er vigtigt at bemærke på dette tidspunkt, at vi også kunne kalde app.post med samme syntaks for indlæg til en URL i modsætning til gets.

Inden for vores anonyme tilbagekald håndterer vi alle indgående data og gengiver en visning for brugeren. Det er her det meste af min forretningslogik ender, så det giver faktisk mening IKKE at bruge anonyme funktioner her. Her er et eksempel på et grundlæggende tilbagekald, der blot viser en hjemmeside:

app.get('/', function(req, res, next){

    //some business logic

    res.render('views/home');
});
 

Når brugeren forsøger at FÅ indeksstien til vores applikation (/ ), gengiver vi simpelthen vores home visning, der fra roden af ​​vores projekt er gemt i en views folder.

Men hvad nu hvis vi ønsker at modularisere dette, så vi ikke erklærer alle vores ruter i vores primære app.js eller server.js ?

Vi bruger module.exports = .. i vores moduler for at fortælle vores server, hvad der præcist skal inkluderes. I min controller eksporterer jeg en enkelt funktion, der tager applikationen som et argument og bruger det til at definere vores ruter som sådan:

Controllers/User.js

 module.exports = function(app){

    app.get('/users', function(req, res){
        var users = req.db.collection('users').find();
        if (!users) {
            console.log("no users found");
            res.redirect('/');
        } else {
            res.render('users/index', {users : users});
        }
    });

};
 

Du skal ikke bekymre dig om req.db kode, vedhæfter jeg databasen til anmodningen i min applikation, men det gøres ikke som standard. Du skal blot forstå, at jeg får en liste over 'brugere' her og omdirigerer brugeren til indekset for min app, hvis der ikke er nogen.

Modeller

Mongoose giver os en fantastisk grænseflade til at skrive modeller. Med mongoose er det at skrive modeller en tretrinsproces:

  • Definer et skema
  • Definer modellogik
  • Generer og eksporter modellen

Her er et eksempel på en User model:

Modeller/User.js

var mongoose = require('mongoose'),
    userSchema = new mongoose.Schema({

        name: { type: String, required: true },
        joinDate: {type: Date, default: date.now }

    }),
    User = mongoose.model('user', userSchema);

module.exports = user;
 

Serverapp

module.exports bruges til at hjælpe os med at definere en vis modularitet til vores kodebase. Når vi kører en nodeapplikation, kører vi i sidste ende en enkelt JavaScript-fil (du har allerede set den fil med server.js eller app.js ).

For at forhindre, at denne fil bliver for stor med flere modeller og ruter, bruger vi require(module) at inkludere kode fra andre JS-filer. module i vores tilfælde ville være en vej til det modul, vi ønsker at kræve. Hvis du har følgende dokumentstruktur:

| Controllers - User.js | Models - User.js | Views app.js

For at inkludere din brugercontroller fra app.js , ville du skrive:require('./Controllers/User') . Da vores controller-moduler blot eksporterer funktioner, kan vi kalde den funktion umiddelbart efter vores require-sætning ved blot at tilføje parenteser i slutningen (med de parametre, der kræves). At inkludere mine controllere ser sådan ud:

require('./Controllers/User')(app)

Jeg går forbi den egentlige app, fordi mit modul (nedenfor) blot eksporterer en funktion, der tilføjer forretningslogik til min apps ruter. Dette skal kun kaldes og aldrig bruges, så jeg fanger ikke min controller som en variabel til at kalde metoder på senere.

Det er lidt anderledes at inkludere modeller, da vi måske ønsker at udføre en operation, som vores model definerer. Vi kan gøre dette ved at ændre vores krævede kode lidt:

var User = require('./Models/User');

Nu kan vi kalde metoder i vores brugermodel når som helst. Mongoose giver os en masse grundlæggende funktionalitet gratis:

User.find({}, function(err, users){ .. });

Ovenstående funktion vil finde alle vores brugere og derefter udføre en anonym funktion med en potentiel err (er null, hvis der ikke er nogen problemer) og derefter en liste over vores brugere i JSON-format. Ret smart.

Ved at kombinere alle disse koncepter opretter du en grundlæggende webapplikation ved hjælp af Express og Node.js. Fortæl mig venligst i kommentarerne, hvis der er noget, jeg kan afklare om, hvordan jeg bruger Express. Dette er viden på meget overfladeniveau, og jeg foreslår, at du graver i dokumentation og ser på plugins for at udvide mulighederne for dine apps. Held og lykke!




  1. Model.findOne returnerer ikke dokumenter, men returnerer et indpakningsobjekt

  2. redis HLL for mange falske positiver

  3. Latterligt langsom mongoDB-forespørgsel på lille samling i enkel, men stor database

  4. Brug $gte og <e mongo-operatoren, hvis dato er i strengformat i mongodb