📜 ⬆️ ⬇️

Building a Nodejs Modular System

Primary requirements


• ease of connecting modules
• standard URL structure
• multilingual
• automatic acceptance of changes
• use of multiprocessor capabilities
The system is based on Express . To facilitate writing the code, use the wait.for module .

File structure



Demonization of the server under Linux


In our project, the forever module was used.
-w - allows you to change modules without directly rebooting the server. Forever monitors the changes and overloads the server as needed.
-l leads to emptiness, since it was decided that the two logs are too much.
forever start -a -w -l /dev/null -o out.log -e err.log Server.js 

Using the capabilities of a multiprocessor system


Running multiple processes through the “cluster” module to distribute the load between the cores.
 // Server.js var cluster = require('cluster'); var workerCount = require('os').cpus().length; cluster.setupMaster({ exec: "app.js" }); // Fork workers. for (var i = 0; i < workerCount ; i++)cluster.fork() 

Module connections


The ease of connecting modules is achieved by two inclusions.
Automatic connection of all routes

 // part of app.js //   routes    var routesPath = path.join(__dirname, 'routes'); //     var routeList = fs.readdirSync(routesPath); for(var i in routeList){ var filePath = path.join(routesPath,routeList[i]); if(fs.statSync(filePath).isFile() && path.extname(routeList[i])=='.js') require(filePath)(app); //   } 

Module connection and function call

Routes are defined separately. in each file, which also achieves unification and ease of connecting routes for the final developer.
 // api.js module.exports = function (app) { app.get('/api/:mod/:lang/:action', function(req, res){action(req,res,global.conf.METHODS.GET);}); app.post('/api/:mod/:lang/:action', function(req, res){action(req,res,global.conf.METHODS.POST);}); app.delete('/api/:mod/:lang/:action', function(req, res){action(req,res,global.conf.METHODS.DELETE);}); app.put('/api/:mod/:lang/:action', function(req, res){action(req,res,global.conf.METHODS.PUT);}); }; function action(req, res, method) { //  var lang = req.params.lang.toUpperCase(); if (global.conf.AVAILABLE_LANGUAGES.indexOf(lang) > -1) { //    var mod = req.params.mod.replace(/[^a-zA-z0-9]+/g,''); //    var action = req.params.action.replace(/[^a-zA-z0-9]+/g,''); //    fs.exists(path.resolve(__dirname, './mod_api/'+mod+".js"),function(ok){ if(ok){ //   var startMode = require('./mod_api/'+mod); try{ //     pub_ wait.launchFiber(startMode['pub_'+action], req, res, lang, method); }catch(err){ res.status(405).pj(405,err.message,"Method Not Allowed"); } }else{ res.status(503).pj(503,null,'Service Unavailable '); } }); } else{ res.status(400).pj(400,null,'Not supported language'); } } 

Implementation of the final function


All functions with the pub_ prefix are public, everything else is private.
 // file routes/mod_api/test.js exports.pub_Start = function(req, res, lang, method){ res.pj(0,(method===global.conf.METHODS.POST)?"POST":"GET","SUCCESS "); } 

Output unification


 //part app.js http.ServerResponse.prototype.pj = function(status,data,message){ try { this.json({STATUS:status,CONTENT:data,MESSAGE:message}); }catch(e) { console.error(e); this.json({STATUS:999,CONTENT:null,MESSAGE:'parse response error'});} }; 


Well, at the end of the function call: api.codevit.net/api/test/en/Start
(I really hope that the server does not fall off, this is my test server)

If someone is interested, I can lay out the skeleton on github.
About syntax errors please write in private.

')

Source: https://habr.com/ru/post/252971/


All Articles