Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi environment Express Api

I am working on an Multi-Environment API based on Express framework. What i want is to keep my configuration dynamic, e.g. This Api would be able to serve both mobile apps and Web apps. If request is coming from mobile source than config-app-1.json should be included, otherwise config-app-2.json.

Currently I have config-app-1.json, config-app-2.json, config-db-1.json, config-db-2.json and a configManager.js class which sets required configuration in app.listen(). In other application modules i require configManager and use the necessary configurations. This however leads to code duplication issue in individual functions. Each function has to get reference of db and application settings in its local scope.

I would like to know what are best practices for a multi-environment API build using Express framework.

like image 506
Muzammil Naseer Avatar asked Oct 18 '22 07:10

Muzammil Naseer


1 Answers

These are configuration files, here is my approach.

File Structure

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

Environment Configs

Configration files are js modules for each device, then the configManager handles which one is active based on device.

//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 Config

Database configurations should be centralized.

Usually you can connect to multiple databases within the same node instance, however it is not recommended. if you absolutely have to, just use two objects (instead of "mongodb" replace with "mobileMongoDb" and "desktopMongoDb") but i recommend that you use one database and divide it into two main documents, or use certain prefixes set in your platform-specific configs.

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

configManager.js (Putting things together)

This is a simple file for demonstration only..

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 from header

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

like image 109
Bamieh Avatar answered Oct 22 '22 02:10

Bamieh