多环境Express Api

我正在开发基于Express框架的多环境API。 我想要的是保持我的configurationdynamic,例如这个Api将能够同时提供移动应用程序和Web应用程序。 如果请求来自移动源,则应该包含config-app-2.json ,否则config-app-2.json

目前我有config-app-1.jsonconfig-app-2.jsonconfig-db-1.jsonconfig-db-2.json和一个在app.listen()设置所需configuration的configManager.js类。 。 在其他应用程序模块中,我需要configManager并使用必要的configuration。 然而,这会导致单个函数中的代码重复问题。 每个函数都必须在本地范围内获取数据库和应用程序设置的引用。

我想知道什么是使用Express框架的多环境API构build的最佳实践。

这些是configuration文件,这是我的方法。

文件结构

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

环境configuration

Configration文件是每个设备的js模块,然后configManager根据设备处理哪一个是活动的。

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

数据库configuration

数据库configuration应该集中。

通常您可以连接到同一节点实例中的多个数据库,但不推荐使用。 如果你绝对必须使用两个对象(而不是“mongodb”replace为“mobileMongoDb”和“desktopMongoDb”),但我build议您使用一个数据库并将其分成两个主要文档,或者使用在您的平台中设置的某些前缀特定的configuration。

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

configManager.js(把东西放在一起)

这是一个简单的文件仅供演示

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

从头部检测移动

阅读更多在这里https://gist.github.com/dalethedeveloper/1503252

您可以设置环境variables。 我通常做的是有多个configuration文件,如你所说的。

然后在本地,开发和生产环境variablesNODE_ENV分别设置为“LOCAL”,“DEVELOPMENT”和“PRODUCTION”。

然后你可以通过下面的代码来引用环境

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

确保在每台服务器的环境中正确设置环境variables。 按照你想要的方式使用从上面的代码中检索的configurationjson。

请求的来源(例如Mobile – Web)可以在运行时更改吗? 换句话说,可以请求1来自移动设备并从networking请求2?

如果是这样,您可以查看标题中的用户代理来确定您正在处理的设备types。 这确实使你依赖于用户代理,如果没有发送,你将无法识别你的客户端。

req.headers['User-Agent'];

如果您自己拥有客户,则可以为每个请求添加一个属性,如额外的标题。 req.headers['X-Client-Type'] = 'Mobile'; //Web req.headers['X-Client-Type'] = 'Mobile'; //Web

这样你就不依赖于用户代理,并且仍然能够识别每个客户的types。

最后,如果你正在和第三方客户打交道,那么其他人可能会打你的API来让你的应用程序注册。 (名称,开发人员姓名,联系信息,可能同意某种types的服务协议,并说明客户端types,Web vs Mobile)。

然后,您可以在每个新请求中获取每个客户端的types。