Class: Rackables::Branch

Inherits:
Object
  • Object
show all
Defined in:
lib/rackables/branch.rb

Overview

Rackables::Branch lets you conditionally re-route the Rack stack at runtime to an alternate endpoint.

You initialize this middleware with a block, which should either 1. return a valid rack endpoint, when want to branch away from the current Rack pipeline, or 2. nil/false, when you want to continue on. The block is passed the current Rack env hash.

config.ru usage example:

use Rackables::Branch do |env|
  ApiApp if env["PATH_INFO"] =~ /\.xml$/
end

run MyEndpointApp

A slightly more complex example with multiple endpoints:

use Rackables::Branch do |env|
  if env['PATH_INFO'] =~ %r{^\/foo\/(bar|baz)(.*)$/}
    env['PATH_INFO'] = $2
    {'bar' => BarApp, 'baz' => BazApp}[$1]
  end
end

run MyEndpointApp

If the app returned from the block responds with an X-Cascade: pass header, control will be passed back to the main rack pipeline.

In this contrived example, MyEndpointApp will always be called:

use Rackables::Branch do |env|
  Proc.new { [404, 'X-Cascade' => 'pass', []] }
end

run MyEndpointApp

Instance Method Summary collapse

Constructor Details

#initialize(app, &block) ⇒ Branch

Returns a new instance of Branch.



40
41
42
43
# File 'lib/rackables/branch.rb', line 40

def initialize(app, &block)
  @app = app
  @block = block
end

Instance Method Details

#call(env) ⇒ Object



45
46
47
48
49
50
51
52
53
# File 'lib/rackables/branch.rb', line 45

def call(env)
  if branch_app = @block.call(env)
    response = branch_app.call(env)
    cascade = response[1]['X-Cascade']
    cascade == 'pass' ? @app.call(env) : response
  else
    @app.call(env)
  end
end