Parent

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 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

app(default_app = nil, &block) click to toggle source
# File lib/rack/builder.rb, line 58
def self.app(default_app = nil, &block)
  self.new(default_app, &block).to_app
end
new(default_app = nil,&block) click to toggle source
# File lib/rack/builder.rb, line 53
def initialize(default_app = nil,&block)
  @use, @map, @run = [], nil, default_app
  instance_eval(&block) if block_given?
end
new_from_string(builder_script, file="(rackup)") click to toggle source
# File lib/rack/builder.rb, line 48
def self.new_from_string(builder_script, file="(rackup)")
  eval "Rack::Builder.new {\n" + builder_script + "\n}.to_app",
    TOPLEVEL_BINDING, file, 0
end
parse_file(config, opts = Server::Options.new) click to toggle source
# 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/, '')
    app = new_from_string cfgfile, config
  else
    require config
    app = Object.const_get(::File.basename(config, '.rb').capitalize)
  end
  return app, options
end

Public Instance Methods

call(env) click to toggle source
# File lib/rack/builder.rb, line 137
def call(env)
  to_app.call(env)
end
map(path, &block) click to toggle source

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 126
def map(path, &block)
  @map ||= {}
  @map[path] = block
end
run(app) click to toggle source

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 103
def run(app)
  @run = app
end
to_app() click to toggle source
# File lib/rack/builder.rb, line 131
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
use(middleware, *args, &block) click to toggle source

Specifies 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 81
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

[Validate]

Generated with the Darkfish Rdoc Generator 2.