Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add plugin and using some external module/file on RT

I'm having node.js application/module which is working OK with plug-in concept ,i.e.

My module is acting like proxy with additional capabilities such as adding new functionality to the out-of-the-box functionality(methods). To do this you need to do the following:

clone my application

create new folder which is called extenders(inside my app)

In this folder you should provide two files

  1. extend.js with your logic as functions/methods
  2. extend.json which define your API (to know which file to invoke)

Note: the JS & JSON file name must be identical

for example lets assume that this is your extend.json file

{
  "extenders": [
    {
        "path": "run",
        "fn": "runFn"
      },
}

In this case when the user put in the browser the following link

localhost:3000/run

Im invoking the runFn function (which exist in the extend.js file)with its logic and this is working as expected (under the hood I read the json & js files and invoke the function like extender[fnName](req, res));

Now I want to support the use case of adding external extender via code for example that the user will do something like

var myModule = require('myModule');

myModule.extend('./pathTo/newExternalPathforExtendersFolder');

so when my module will run it search weather there is new external extenders exist with all configuration and if so refer to it in RT (to the js&json files).

My questions are:

  1. I need to find when my module is starting who is register to my module and then do my logic on this module , how it can be done in node?

2.if there is other solution in node please let me know.

like image 809
07_05_GuyT Avatar asked Apr 25 '16 12:04

07_05_GuyT


2 Answers

You could implement initialization function in your api to give freedom to module users. For example.

var yourModule = require('yourModule').init({
  extenders: [
    {
      "path": "run",
      "fn": "runFn"
    }
  ]
});

yourModule.listen(3000);

Or as MattW wrote you can implement it like an express middleware, so module users could use it with their own server. For example:

var yourModule = require('yourModule').init({
  extenders: [
    {
      "path": "run",
      "fn": "runFn"
    }
  ]
});

app = require('express')();
app.use(yourModule.getMiddleware());

Look at webpack-dev-server, webpack-dev-middleware like another example. Hope there's some similarity with your task. Webpack also deals with fs and configs. They've just splitted middleware and standalone server to separate modules. And there's no "working code", because we need your module's code, to talk about wrapper, which would depend on yourModule implementation. Just some thoughts.

like image 71
Fake Fish Avatar answered Nov 05 '22 09:11

Fake Fish


If i'm not wrong understanding your problem maybe this approach can help you.

I think you could list your extenders in an ACL like JSON which not only include the path or the fnName, but the file_to_js path or any other property you need, like if it's active or security parameters.

extenders: [
   {
     "path": "run",
     "fn": "runFn",
     "file": "file_path"
     "api-key": true,
     "active": true
   }
]

Then you can preload your modules reading ACL json and let them cached ready for extend.

var Router = {
    extenders: {},
    init: function () {
        this.extenders = {};
        this.loadExtenderFiles();
    },
    loadExtenderFiles: function () {
        var key, extender;
        // Iterate extender files
        for (key in ACL_JSON) {
            // extender load logic
            extender = ACL_JSON[key];
            if (extender.active) {
                this.extenders[extender.fn] = require(extender.file);
            }
        }

    },
    // this fn should allow you to Router.extend() anywhere during the request process
    extend: function (fn, request, response) {
        // Parse request/response to match your extender module pattern
        // extender process logic
        this.extenders[fn](request, response);
    }
};
module.exports = Router;

So Router.init() should do the cache work on server init; Router.extend() should resolve your api request or extend one being processed.

Hope it helps you!

like image 30
gtrenco Avatar answered Nov 05 '22 07:11

gtrenco