2012-09-14 5 views
5

Ho un'app Expressjs in esecuzione su NodeJS 0.8.8 usando MongoDB e il linguaggio template Jade, e vorrei consentire all'utente di configurare molte delle opzioni di presentazione a livello di sito come i titoli delle pagine, l'immagine del logo, ecc.Come posso archiviare la configurazione del sito in MongoDB per un'app NodeJS Express?

Come posso archiviare queste opzioni di configurazione in un database mongoDB in modo da poterle leggere all'avvio dell'applicazione, manipolarle mentre l'app è in esecuzione e visualizzarle nei modelli di giada?

Ecco la mia messa a punto generale app:

var app = module.exports = express(); 
global.app = app; 
var DB = require('./accessDB'); 
var conn = 'mongodb://localhost/dbname'; 
var db; 

// App Config 
app.configure(function(){ 
    ... 
}); 

db = new DB.startup(conn); 

//env specific config 
app.configure('development', function(){ 
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
}); // etc 

// use date manipulation tool moment 
app.locals.moment = moment; 

// Load the router 
require('./routes')(app); 

Finora ho creato un modello chiamato "Sito" per la collezione "SiteConfig" e ho una funzione chiamata getSiteConfig in accessDB.js che corre Site.find() ... per recuperare i campi nell'unico documento nella raccolta.

Quindi questo è il punto cruciale della domanda: come devo iniettare quei campi nell'app Express in modo che possano essere utilizzati in tutto il sito? Dovrei seguire lo stesso schema che ho usato con lo strumento moment.js? In questo modo:

db.getSiteConfig(function(err, siteConfig){ 
    if (err) {throw err;} 
    app.locals.siteConfig = siteConfig; 
}); 

In caso contrario, quale sarebbe il modo corretto di farlo?

Grazie!

+0

è questo qualcosa che si desidera memorizzare nella sessione? – c0deNinja

+0

No, non ci credo. Non voglio che il client abbia accesso ad esso. Voglio solo che l'app express lato server (specialmente Jade) abbia accesso ad essa. Ho funzionato fino al punto di un console.log. Credo che dovrei solo provare ad aggiungerlo ad app.locals e vedere cosa succede, ma non sono sicuro delle implicazioni sulla sicurezza dell'utilizzo di questo. (o la stabilità di esso) – tutley

risposta

16

Considerare l'utilizzo del middleware espresso per caricare la configurazione del sito.

app.configure(function() { 
    app.use(function(req, res, next) { 
    // feel free to use req to store any user-specific data 
    return db.getSiteConfig(req.user, function(err, siteConfig) { 
     if (err) return next(err); 
     res.local('siteConfig', siteConfig); 
     return next(); 
    }); 
    }); 
    ... 
}); 

Lanciare un errore è davvero una pessima idea in quanto causerà il crash dell'applicazione. Quindi utilizzare next(err);. Passerà il tuo errore per esprimere errorHandler.

Se già autenticato l'utente (in middleware precedente, per esempio) e memorizzati i suoi dati in req.user, è possibile utilizzarlo per ottenere il config direttamente dal db.

Attenzione però all'uso della funzione getSiteConfig all'interno del middleware espresso in quanto si interromperà espressamente dall'ulteriore elaborazione della richiesta fino al ricevimento dei dati.

È necessario prendere in considerazione la memorizzazione nella cache della sessione siteConfig per accelerare l'applicazione. Memorizzare i dati specifici della sessione nella sessione express è assolutamente sicuro perché non c'è modo per l'utente di accedervi.

Il codice seguente illustra l'idea di caching siteConfig in sessionn espresso:

app.configure(function() { 
    app.use(express.session({ 
    secret: "your sercret" 
    })); 
    app.use(/* Some middleware that handles authentication */); 
    app.use(function(req, res, next) { 
    if (req.session.siteConfig) { 
     res.local('siteConfig', req.session.siteConfig); 
     return next(); 
    } 
    return db.getSiteConfig(req.user, function(err, siteConfig) { 
     if (err) return next(err); 
     req.session.siteConfig = siteConfig; 
     res.local('siteConfig', siteConfig); 
     return next(); 
    }); 
    }); 
    ... 
}); 
+1

Questa è una grande risposta e lo apprezzo molto. Purtroppo non posso votare perché non ho abbastanza reputazione, ma se qualcuno sta guardando questo, per favore vota. Grazie ancora. – tutley

Problemi correlati