IOverThoughtThis

Recovering Perfectionist

Passing Arguments to Sinatra Apps

Campaigns at Release are developed as standalone Sinatra apps which are mounted (at run time) depending on the type of campaign that is required. This means we can skip the type == 'something' ? ... statements and simply define separate sinatra apps to run our campaigns.


    class Campaign1
    end

    ...

    class Campaign2
    end

    ...

    Rack::Builder.new do
      map '/' do
        run Object.const_get(campaign_type)
      end
    end
  

This has meant that development of each type of campaign is less complex.

One of the challenges I faced was with dependency injection. I wanted to pass in my command_handler and my read_view (I'm playing with Event Sourcing/CQRS) .

The issue is, the Rack::Builder#run method doesn't provide a way to pass arguments into the app!

After looking at the rack code and reading this on Sinatra, I discovered that I could pass arguments fairly easy by accessing the @app instance variable of the Rack::Builder object.

I ended up with this.


    class Campaign1
      def initialize(app = nil, command_handler: nil, read_view: nil)
        super(app)
        @command_handler = command_handler
        @read_view = read_view
      end
      ...
    end

    Rack::Builder.new do
      map '/' do
        run Object.const_get(campaign_type).new(@app, {
          command_handler: command_handler,
          read_view: read_view
        })
      end
    end
  

This works like a charm.

Some names have been changed to protect my inability to name things well.

Peace.