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