2016-06-09 9 views
5

Sto lavorando su un'API multi-ambiente basata su framework Express. Quello che voglio è mantenere la mia configurazione dinamica, ad es. Questa Api sarebbe in grado di servire sia le app mobili che le app Web. Se la richiesta proviene da una fonte mobile di , è necessario includere config-app-1.json, altrimenti config-app-2.json.Multi environment Express Api

Attualmente ho config-app-1.json, config-app-2.json, config-db-1.json, config-db-2.json e una classe configManager.js che mette configurazione richiesta in app.listen(). In altri moduli applicativi ho bisogno di configManager e uso le configurazioni necessarie. Ciò tuttavia porta al problema della duplicazione del codice nelle singole funzioni. Ogni funzione deve ottenere il riferimento di db e delle impostazioni dell'applicazione nel suo ambito locale.

Vorrei sapere quali sono le best practice per una generazione di API multi-ambiente utilizzando il framework Express.

+1

Puoi aggiungere porzioni del tuo codice che possono spiegare il tuo problema . –

risposta

1

Questi sono file di configurazione, ecco il mio approccio.

Struttura del file

. 
├── app.js 
├── _configs 
| ├── configManager.js 
| ├── database.js 
| └── platform 
|  ├── mobile.js 
|  └── desktop.js 

file Ambiente Configs

configration sono moduli js per ogni dispositivo, quindi il configmanager gestisce quello attivo sulla base di dispositivo.

//mobile.js example 
module.exports = { 
    device: 'mobile', 
    configVar: 3000, 
    urls: { 
     base: 'DEVICE_SPECIFIC_BASE_URL', 
     api: 'DEVICE_SPECIFIC_BASE_URL' 
    }, 
    mixpanelKey: 'DEVICE_SPECIFIC_BASE_URL', 
    apiKey: "DEVICE_SPECIFIC_BASE_URL", 
} 

database di configurazione

configurazioni del database dovrebbero essere centralizzate.

In genere è possibile connettersi a più database all'interno della stessa istanza del nodo, tuttavia non è consigliabile. se devi assolutamente, usa solo due oggetti (invece di "mongodb" sostituisci con "mobileMongoDb" e "desktopMongoDb") ma ti consiglio di usare un database e dividerlo in due documenti principali, o usare determinati prefissi impostati nella tua piattaforma -Config specifici

// databse.js example 
module.exports= { 
    mongodb: { 
    host  : 'localhost', 
    port  : 27017, 
    user  : '', 
    password : '', 
    database : 'DB_NAME' 
    }, 
} 

configManager.js (mettere le cose insieme)

Si tratta di un semplice file solo per la dimostrazione ..

var userAgent = req.headers['User-Agent']; 
var isMobile = /Mobile|Android|/i.test(userAgent); 



// require them all to be cached when you run node. 
var configs = { 
    mobile: require('./platform/mobile'), 
    desktop: require('./platform/desktop') 
} 
var activeConfig = isMobile? configs.mobile : configs.desktop; 
var dbConfigs = require('./databse'); 


var mongoose = require('mongoose'); 
var express = require('express'); 
var app = express(); 

app.get('/', function (req, res) { 
    var finalresp = 'Hello from '; 
    finalresp += isMobile? 'mobile' : 'desktop; 
    finalresp += activeConfig.configVar; 
    res.send(finalresp); 
}); 

mongoose.connect(dbConfigs.mongodb.host, function(err) { 
    if(isMobile) { /* ... */ } 
}); 

Detect Mobile dal colpo di testa

Read more here https://gist.github.com/dalethedeveloper/1503252

1

È possibile impostare le variabili di ambiente. Quello che faccio di solito è avere più file di configurazione come hai menzionato.

Quindi impostare la variabile di ambiente NODE_ENV in locale, sviluppo e produzione come "LOCAL", "DEVELOPMENT" e "PRODUCTION" rispettivamente.

Poi si può fare riferimento l'ambiente seguente codice

ENV = process.env.NODE_ENV 
if(ENV === 'PRODUCTION') { 
    mainConf = JSON.parse(fs.readFileSync(path.join(__dirname, '/config/main-production.json'))) 
    dbConf = JSON.parse(fs.readFileSync(path.join(__dirname, '/config/db-production.json'))) 

} else if(ENV === 'DEVELOPMENT') { 
    mainConf = JSON.parse(fs.readFileSync(path.join(__dirname, '/config/main-development.json'))) 
    dbConf = JSON.parse(fs.readFileSync(path.join(__dirname, '/config/db-development.json'))) 
} else if(ENV === 'LOCAL') { 
    mainConf = JSON.parse(fs.readFileSync(path.join(__dirname, '/config/main-local.json'))) 
    dbConf = JSON.parse(fs.readFileSync(path.join(__dirname, '/config/db-local.json'))) 
} 

Assicurarsi di impostare correttamente le variabili d'ambiente in ambiente di ciascun server. Usa il config json recuperato dal codice sopra nel modo desiderato.

+0

Questo non funzionerà nel mio caso, le variabili d'ambiente non possono cambiare in fase di esecuzione. Quello che sto cercando è di cambiare la mia configurazione sui parametri di base della richiesta. –

1

La sorgente della richiesta (ad esempio Mobile - Web) può cambiare durante il runtime? In altre parole, puoi richiedere 1 provenire da un dispositivo mobile e richiedere 2 dal web?

In tal caso, è possibile esaminare l'agente utente nelle intestazioni per determinare il tipo di dispositivo con cui si ha a che fare. Questo però ti rende dipendente dall'agente utente e, se non viene inviato, non avrai modo di identificare il tuo cliente.

req.headers['User-Agent'];

Se siete il proprietario i clienti da soli, è possibile aggiungere una proprietà ad ogni richiesta, dire un header supplementare. req.headers['X-Client-Type'] = 'Mobile'; //Web.

In questo modo non si è dipendenti dal programma utente e si è ancora in grado di identificare il tipo di ciascun client.

Infine, se hai a che fare con clienti di terze parti, altre persone che fanno applicazioni per raggiungere la tua API potrebbero voler far loro registrare la loro applicazione. (Nome, nome dello sviluppatore, informazioni di contatto, forse accettare un qualche tipo di contratto di servizio e indicare anche il tipo di client, Web vs Mobile).

Sareste quindi in grado di recuperare il tipo di ogni client su ogni nuova richiesta.

Problemi correlati