class Rack::Builder
Rack::Builder implements a small DSL to iteratively construct Rack applications.
Example:
require 'rack/lobster' app = Rack::Builder.new do use Rack::CommonLogger use Rack::ShowExceptions map "/lobster" do use Rack::Lint run Rack::Lobster.new end end run app
Or
app = Rack::Builder.app do use Rack::CommonLogger run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['OK']] } end run app
use
adds a middleware to the stack, run
dispatches to an application. You can use map
to construct a
Rack::URLMap in a convenient way.
Public Class Methods
# File lib/rack/builder.rb, line 54 def self.app(default_app = nil, &block) self.new(default_app, &block).to_app end
# File lib/rack/builder.rb, line 49 def initialize(default_app = nil,&block) @use, @map, @run = [], nil, default_app instance_eval(&block) if block_given? end
# File lib/rack/builder.rb, line 32 def self.parse_file(config, opts = Server::Options.new) options = {} if config =~ /\.ru$/ cfgfile = ::File.read(config) if cfgfile[/^#\(.*)/] && opts options = opts.parse! $1.split(/\s+/) end cfgfile.sub!(/^__END__\n.*\Z/m, '') app = eval "Rack::Builder.new {\n" + cfgfile + "\n}.to_app", TOPLEVEL_BINDING, config, 0 else require config app = Object.const_get(::File.basename(config, '.rb').capitalize) end return app, options end
Public Instance Methods
# File lib/rack/builder.rb, line 133 def call(env) to_app.call(env) end
Creates a route within the application.
Rack::Builder.app do map '/' do run Heartbeat end end
The use
method can also be used here to specify middleware to
run under a specific path:
Rack::Builder.app do map '/' do use Middleware run Heartbeat end end
This example includes a piece of middleware which will run before requests
hit Heartbeat
.
# File lib/rack/builder.rb, line 122 def map(path, &block) @map ||= {} @map[path] = block end
Takes an argument that is an object that responds to call and returns a Rack response. The simplest form of this is a lambda object:
run lambda { |env| [200, { "Content-Type" => "text/plain" }, ["OK"]] }
However this could also be a class:
class Heartbeat def self.call(env) [200, { "Content-Type" => "text/plain" }, ["OK"]] end end run Heartbeat
# File lib/rack/builder.rb, line 99 def run(app) @run = app end
# File lib/rack/builder.rb, line 127 def to_app app = @map ? generate_map(@run, @map) : @run fail "missing run or map statement" unless app @use.reverse.inject(app) { |a,e| e[a] } end
Specifies a middleware to use in a stack.
class Middleware def initialize(app) @app = app end def call(env) env["rack.some_header"] = "setting an example" @app.call(env) end end use Middleware run lambda { |env| [200, { "Content-Type => "text/plain" }, ["OK"]] }
All requests through to this application will first be processed by the
middleware class. The call
method in this example sets an
additional environment key which then can be referenced in the application
if required.
# File lib/rack/builder.rb, line 77 def use(middleware, *args, &block) if @map mapping, @map = @map, nil @use << proc { |app| generate_map app, mapping } end @use << proc { |app| middleware.new(app, *args, &block) } end
Private Instance Methods
# File lib/rack/builder.rb, line 139 def generate_map(default_app, mapping) mapped = default_app ? {'/' => default_app} : {} mapping.each { |r,b| mapped[r] = self.class.new(default_app, &b) } URLMap.new(mapped) end