Project

hobby

0.0
No commit activity in last 3 years
No release in over 3 years
There's a lot of open issues
A Ruby DSL over Rack. You can create with it reusable web applications, suitable for both standalone and inside-Rails use.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

~> 2
 Project Readme

Introduction

A Ruby DSL over Rack. You can create with it reusable web applications, suitable for both standalone and inside-Rails use.

Installation

Add this line to your application’s Gemfile:

gem 'hobby'
# or this if you want to use hobby master
# gem 'hobby', github: 'ch1c0t/hobby'

And then execute:

$ bundle

Or install it yourself as:

$ gem install hobby

Usage

To create a Hobby application, you create a class and include Hobby in it. For example:

require 'hobby'

class C
  include Hobby

  get "/hello" do
    "Hello, world."
  end
end

Then, you can create an instance of C with

C.new

which will return a Rack application(an object which complies to Rack SPEC).

Because a Hobby application is just a Ruby class, you can do with it pretty much anything you would expect to be able to do with a Ruby class.

Using #initialize

You can set some state in #initialize and then use it in the route’s action:

class C
  include Hobby

  def initialize name
    @name = name
  end

  get "/hello" do
    "Hello, #{@name}."
  end
end

Using instance methods

class C
  include Hobby

  def initialize name
    @name = name
  end

  def name
    @name.upcase
  end

  get "/hello" do
    "Hello, #{name}."
  end
end

How to run

To run an application, you can put it into config.ru:

run C.new 'Hobby'

and then use rackup:

$ rackup

Or, if you are using Rails, you can mount it in config/routes.rb with:

mount C.new('Hobby') => '/some_path'

Routes

For common HTTP verbs, Hobby provides the route definers(methods named accordingly):

class App
  include Hobby

  get { 'Some string.' }
  post { 'Some string.' }
  put { 'Some string.' }
  patch { 'Some string.' }
  delete { 'Some string.' }
  # TODO: find a good example for `options`
end

A definer should be called with a path(optional) and an action(passed as a block).

Calling a definer has a side effect of defining a route in the router. When an incoming request matches a route, the action is executed and a response is sent back to the client. The return value of the action will be the body of the response.

Default route

If a path was omitted

get do
  'The body returned to the HTTP client making the request.'
end

the action is attached to the root route, like if

get '/' do
  'The body returned to the HTTP client making the request.'
end

were called.

Route params

Can be accessed with route.params (or a shortcut my):

# will match '/index', '/hobby', '/purpose', etc.
get '/:name' do
  route.params[:name]
end

# will match '/index.css', '/index.js', etc.
get '/:name.:ext' do
  "The name is #{my[:name]} and the ext is #{my[:ext]}."
end

Default methods

The following methods are predefined:

  • env: a Hash, a Rack environment.

  • request: a Rack::Request.

  • response: a Rack::Response.

  • route: a Hobby::Router::Route, the currently executing route.

  • route.params, or a shortcut my: a Hash which stores route params. See Route params for a usage example.

  • halt: returns the response immediately. See Halting for a usage example.

Halting

class App
  include Hobby

  use Rack::Session::Cookie, secret: SecureRandom.hex(64)

  def session
    env['rack.session']
  end

  get '/' do
    response.status = 401
    halt
    'This line is never going to be returned.'
  end
end

Extensions

You can extend Hobby with usual modules:

module MyExtension
  def do_something
    # do something
  end
end

class App
  include Hobby
  include MyExtension

  get '/' do
    do_something
    'Hello World!'
  end
end

Available extensions

Using Rack::Builder

You can use map and use from Rack::Builder.

Mapping applications

You can mount any Rack application to a Hobby application with map. Here is an example of mounting the application from Using #initialize to '/anatoly' and '/patricio' routes:

class App
  include Hobby

  map '/anatoly', C.new('Anatoly')
  map '/patricio', C.new('Patricio')

  get '/' do
    'Mapping app.'
  end
end

Using middleware

You can use any Rack middleware with use:

class App
  include Hobby

  use Rack::Session::Cookie, secret: SecureRandom.hex(64)
  use Rack::ShowExceptions

  def session
    env['rack.session']
  end

  get '/' do
    session[:name] = 'username'
  end
end

Development

To run the specs:

bundle exec rspec