Search code examples
javascriptnode.jsarchitecturerabbitmqamqp

Reuse parameter of callback / Reuse channel


I would like to reuse a RabbitMQ channel in different node modules. Since the channel is created asynchronously, I am not sure what the best approach would be to "inject" this channel object to other modules.

If possible, I would like to avoid external dependencies like DI containers for this.

Below, you find my simplified code.

Thank you in advance for any advice.

web.js

require('./rabbitmq')(function (err, conn) {
    ...

    // Start web server
    var http = require('./http');
    var serverInstance = http.listen(process.env.PORT || 8000, function () {
        var host = serverInstance.address().address;
        var port = serverInstance.address().port;

    });
});

rabbitmq.js:

module.exports = function (done) {
    ...

    amqp.connect(rabbitMQUri, function (err, conn) {
       ...

        conn.createChannel(function(err, ch) {
            ...
            // I would like to reuse ch in other modules
        });
    });
}

someController.js

module.exports.post = function (req, res) {
   // Reuse/inject "ch" here, so I can send messages
}

Solution

  • you could always attach your channel handle to global object and it can be accessed across module:

    // rabbitmq.js
        
    global.ch = ch
        
    // someController.js
        
    global.ch // <- is the channel instance 
    

    I would prefer to inject the handle into each function because i think it is more explicit and easier to reason about and unittest. You could do that with partial function application

    with lodash:

    var post = function (req, res, rabbitMQchannel) {
        // Reuse/inject "ch" here, so I can send messages
    }
        
    var ch = getYourChannel();
    
    // post is function object that accepts two params, and the
    // third is bound to your channel
    
    module.exports.post = _.partialRight(post, ch);
    

    a third option is to have rabbitmq.js export a function to getting a channel. A channel could be a singleton so there would only ever be one instance of it. Then any method that whats a channel handle would request one from the method, which wouldn't require channels to be passed around through functions, or globally.