GitHub

Inspired by Rack, empowers mruby, a work in progress!

Rack provides a minimal, modular, and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call.

The exact details of this are described in the Rack specification, which all Rack applications should conform to.

-- https://github.com/rack/rack

Shelf::Builder.app do
  run ->(env) { [200, {}, ['A barebones shelf app']] }
end

Installation

Add the line below to your build_config.rb:

MRuby::Build.new do |conf|
  # ... (snip) ...
  conf.gem 'mruby-shelf'
end

Or add this line to your aplication's mrbgem.rake:

MRuby::Gem::Specification.new('your-mrbgem') do |spec|
  # ... (snip) ...
  spec.add_dependency 'mruby-shelf'
end

Builder

The Rack::Builder DSL is compatible with Shelf::Builder. Shelf uses mruby-r3 for the path dispatching to add some nice extras.

app = Shelf::Builder.app do
  run ->(env) { [200, { 'content-type' => 'text/plain' }, ['A barebones shelf app']] }
end
app.call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/')
# => [200, { 'content-type' => 'text/plain' }, ['A barebones shelf app']]
app.call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/info')
# => [404, { 'content-type' => 'text/plain', 'X-Cascade' => 'pass' }, ['Not Found']]

Using middleware layers is dead simple:

class NoContent
  def initialize(app)
    @app = app
  end
  def call(env)
    [204, @app.call(env)[1], []]
  end
end
app = Shelf::Builder.app do
  use NoContent
  run ->(env) { [200, { ... }, ['A barebones shelf app']] }
end
app.call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/')
# => [204, { ... }, []]

Mounted routes may contain slugs and can be restricted to a certain HTTP method:

app = Shelf::Builder.app do
  get('/users/{id}') { run ->(env) { [200, { ... }, [env['shelf.request.query_hash'][:id]]] } }
end
app.call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/users/1')
# => [200, { ... }, ['1']]
app.call('REQUEST_METHOD' => 'PUT', 'PATH_INFO' => '/users/1')
# => [405, { ... }, ['Method Not Allowed']]

Routes can store any kind of additional data:

"app = Shelf::Builder.app do get('data', [Object.new]) { run ->(env) { [200, { ... }, env['shelf.r3.data']] } } end app.call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/data') # => [200, { ... }, ['#

Read the original on github.com ↗