2016-06-09 9 views
5

Ich arbeite an einer Multi-Environment API basierend auf Express-Framework. Ich möchte, dass meine Konfiguration dynamisch bleibt, z. Diese API wäre in der Lage, sowohl mobile Apps als auch Web-Apps zu bedienen. Wenn eine Anfrage von einer mobilen Quelle kommt, sollte config-app-1.json enthalten sein, andernfalls config-app-2.json.Multi-Umgebung Express Api

Zur Zeit habe ich config-app-1.json, config-app-2.json, config-db-1.json, config-db-2.json und eine configManager.js Klasse, die in app.listen() erforderliche Konfiguration setzt. In anderen Anwendungsmodulen benötige ich configManager und verwende die notwendigen Konfigurationen. Dies führt jedoch zu Codedoppelproblemen in einzelnen Funktionen. Jede Funktion muss in ihrem lokalen Gültigkeitsbereich den Verweis auf die Datenbank- und Anwendungseinstellungen abrufen.

Ich würde gerne wissen, was Best Practices für eine Multi-Umgebung API-Build mit Express-Framework sind.

+1

Können Sie Teile Ihres Codes hinzufügen, die Ihr Problem erklären können . –

Antwort

1

Das sind Konfigurationsdateien, hier ist mein Ansatz.

Dateistruktur

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

Umwelt Configs

Configration Dateien js Module für jedes Gerät sind, kümmert sich dann um die ConfigManager, welche basierend auf dem Gerät aktiv ist.

//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", 
} 

Datenbank Config

Datenbank Konfigurationen sollte zentralisiert werden.

Normalerweise können Sie eine Verbindung mit mehreren Datenbanken innerhalb derselben Knoteninstanz herstellen, dies wird jedoch nicht empfohlen. Wenn Sie unbedingt müssen, verwenden Sie einfach zwei Objekte (anstelle von "mongodb" ersetzen durch "mobileMongoDb" und "desktopMongoDb"), aber ich empfehle, dass Sie eine Datenbank verwenden und teilen Sie es in zwei Hauptdokumente oder verwenden Sie bestimmte Präfixe in Ihrer Plattform -spezifische Konfigurationen

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

configManager.js (Putting Dinge zusammen)

Dies ist eine einfache Datei für Demonstration nur ..

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) { /* ... */ } 
}); 

Mobil Detect von Header

lesen Sie hier mehr https://gist.github.com/dalethedeveloper/1503252

1

Sie können Umgebungsvariablen festlegen. Was ich normalerweise mache, ist, wie erwähnt, mehrere Konfigurationsdateien zu haben.

Dann setzen Sie die Umgebungsvariable NODE_ENV in lokaler, Entwicklung und Produktion als "LOCAL", "DEVELOPMENT" und "PRODUCTION".

Dann können Sie die Umgebung beziehen, die durch folgenden Code

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'))) 
} 

Stellen Sie sicher, dass die Umgebungsvariablen richtig auf die Umwelt jedes Servers. Verwenden Sie die aus dem obigen Code abgerufene Konfigurations-JSON wie Sie möchten.

+0

Das funktioniert in meinem Fall nicht, Umgebungsvariablen können zur Laufzeit nicht geändert werden. Nach was ich suche, ist, meine Konfiguration auf den Basisanforderungsparametern zu ändern. –

1

Kann sich die Quelle der Anfrage (z. B. Mobile - Web) während der Laufzeit ändern? Mit anderen Worten: Kann Anfrage 1 von einem mobilen Gerät kommen und 2 aus dem Web anfordern?

Wenn dies der Fall ist, können Sie den Benutzeragenten in den Kopfzeilen anzeigen, um festzustellen, mit welcher Art von Gerät Sie arbeiten. Dies macht Sie jedoch abhängig vom Benutzer-Agent, und wenn es nicht gesendet wird, haben Sie keine Möglichkeit, Ihren Client zu identifizieren.

req.headers['User-Agent'];

Wenn Sie die Clients selbst besitzen, können Sie eine Eigenschaft auf jede Anfrage hinzufügen können, sagen einen zusätzlichen Header. req.headers['X-Client-Type'] = 'Mobile'; //Web.

Auf diese Weise sind Sie nicht vom Benutzeragenten abhängig und können trotzdem den Typ jedes Clients identifizieren.

Wenn Sie drittens mit Clients von Drittanbietern arbeiten, können andere Personen, die Anwendungen auf Ihre API anwenden, die Registrierung ihrer Anwendung veranlassen. (Name, Name des Entwicklers, Kontaktinformationen, möglicherweise einer Art von Servicevereinbarung zustimmen und auch den Typ des Clients angeben, Web vs Mobile).

Sie könnten dann den Typ jedes Clients bei jeder neuen Anforderung abrufen.