Class: Junkfood::Rack::ChainedRouter

Inherits:
Object
  • Object
show all
Defined in:
lib/junkfood/rack/chained_router.rb

Overview

A Rack Application and Middleware that will execute a list of callables in order until it receives a response without the ‘X-Cascade’ header value set to ‘pass’. ChainedRouter will then return the response of said execution. The response of the last callable will be returned if it is executed even if it has the ‘X-Cascade’ header set. As Middleware, the given app will be the last callable in the chain.

Example as Middleware:

use Junkfood::Rack::ChainedRouter do |router|
  router.add_route Proc.new { |env|
    # This proc is called, but it returns a pass.
    [404, { 'X-Cascade' => 'pass' }, []]
  }
  router.add_route Proc.new { |env|
    # This proc is called, but it also returns a pass.
    [404, { 'X-Cascade' => 'pass' }, []]
  }
end
run Proc.new { |env|
  # The main app is the last callable in ChainRouter's list.
  # And this will be executed.
  [200, { 'Content-Type' => 'text/plain' }, ['Hello World']]
}

Example as Application:

run Junkfood::Rack::ChainedRouter.new do |router|
  router.add_route Proc.new { |env|
    # This proc is called, but it returns a pass.
    [404, { 'X-Cascade' => 'pass' }, []]
  }
  router.add_route Proc.new { |env|
    # This is the last app to run.
    [200, { 'Content-Type' => 'text/plain' }, ['Hello World']]
  }
  router.add_route Proc.new { |env|
    # So this proc is never called.
    [200, { 'Content-Type' => 'text/plain' }, ['Never Run']]
  }
end

Constant Summary collapse

HTTP_NOT_FOUND =

HTTP Not Found status code.

404.freeze
CONTENT_TYPE =

Header to set the content type value in the response.

'Content-Type'.freeze
X_CASCADE =

Header location where to look for the pass value.

'X-Cascade'.freeze
PASS =

The pass string to signify triggering the next callable in the list.

'pass'.freeze

Instance Method Summary collapse

Constructor Details

#initialize(app = nil) {|router| ... } ⇒ ChainedRouter

Returns a new instance of ChainedRouter.

Parameters:

  • app (defaults to: nil)

    the rack application. This will be last callable in chain.

Yields:

  • (router)

    block to configure the ChainedRouter.

Yield Parameters:

  • router

    newly instantiated ChainedRouter



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/junkfood/rack/chained_router.rb', line 85

def initialize(app=nil, &block)
  @chain = []
  if block_given?
    yield self
  end
  @chain << app if app.respond_to? :call

  # Just validate the arguments
  @chain.each do |link|
    raise ArgumentError unless link.respond_to? :call
  end
end

Instance Method Details

#add_route(app) ⇒ Object

Appends a callable to the end of the call chain.

Parameters:

  • app

    the callable to append.



125
126
127
# File 'lib/junkfood/rack/chained_router.rb', line 125

def add_route(app)
  @chain << app
end

#call(env) ⇒ Object

Parameters:

  • the

    rack request environment.



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/junkfood/rack/chained_router.rb', line 101

def call(env)
  # Set some defaults if the route set is empty.
  results = [
    HTTP_NOT_FOUND,
    {
      X_CASCADE => PASS,
      CONTENT_TYPE => 'text/plain'
    },
    []]
  # Call each link in chain.
  for link in @chain
    results = link.call env
    return results unless results[1][X_CASCADE] == PASS
  end
  # Return the results of the last link in chain, or the originally
  # set results if chain is empty.
  return results
end