{"id":13858720,"url":"https://github.com/patriciomacadden/hobbit","last_synced_at":"2025-04-04T07:06:19.313Z","repository":{"id":7989317,"uuid":"9395110","full_name":"patriciomacadden/hobbit","owner":"patriciomacadden","description":"A minimalistic microframework built on top of Rack.","archived":false,"fork":false,"pushed_at":"2020-12-30T18:56:58.000Z","size":132,"stargazers_count":273,"open_issues_count":6,"forks_count":22,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-28T06:07:01.877Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/patriciomacadden.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-04-12T13:42:17.000Z","updated_at":"2024-12-31T15:32:01.000Z","dependencies_parsed_at":"2022-08-20T11:31:05.220Z","dependency_job_id":null,"html_url":"https://github.com/patriciomacadden/hobbit","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patriciomacadden%2Fhobbit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patriciomacadden%2Fhobbit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patriciomacadden%2Fhobbit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patriciomacadden%2Fhobbit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patriciomacadden","download_url":"https://codeload.github.com/patriciomacadden/hobbit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247135143,"owners_count":20889420,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-05T03:02:18.688Z","updated_at":"2025-04-04T07:06:19.294Z","avatar_url":"https://github.com/patriciomacadden.png","language":"Ruby","funding_links":[],"categories":["Ruby","Web Frameworks","Micro Frameworks inspired by Sinatra","Frameworks","Web framework for Ruby"],"sub_categories":[],"readme":"# Hobbit [![Build Status](http://img.shields.io/travis/patriciomacadden/hobbit.svg)](https://travis-ci.org/patriciomacadden/hobbit) [![Code Climate](http://img.shields.io/codeclimate/github/patriciomacadden/hobbit.svg)](https://codeclimate.com/github/patriciomacadden/hobbit) [![Code Climate Coverage](http://img.shields.io/codeclimate/coverage/github/patriciomacadden/hobbit.svg)](https://codeclimate.com/github/patriciomacadden/hobbit) [![Dependency Status](http://img.shields.io/gemnasium/patriciomacadden/hobbit.svg)](https://gemnasium.com/patriciomacadden/hobbit) [![Gem Version](http://img.shields.io/gem/v/hobbit.svg)](http://badge.fury.io/rb/hobbit)\n\nA minimalistic microframework built on top of [Rack](http://rack.github.io/).\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'hobbit'\n# or this if you want to use hobbit master\n# gem 'hobbit', github: 'patriciomacadden/hobbit'\n```\n\nAnd then execute:\n\n```bash\n$ bundle\n```\n\nOr install it yourself as:\n\n```bash\n$ gem install hobbit\n```\n\n## Features\n\n* DSL inspired by [Sinatra](http://www.sinatrarb.com/).\n* [Speed](https://github.com/luislavena/bench-micro).\n* Extensible with standard ruby classes and modules, with no extra logic. See\n[hobbit-contrib](https://github.com/patriciomacadden/hobbit-contrib).\n* Zero configuration.\n\n## Philosophy\n\n* [Don't repeat yourself](http://en.wikipedia.org/wiki/Don't_repeat_yourself)\n* Encourages the understanding and use of [Rack](http://rack.github.io/) and\nits extensions instead of providing such functionality.\n\n## Usage\n\nHobbit applications are just instances of classes that inherits from\n`Hobbit::Base`, which complies the\n[Rack SPEC](http://rubydoc.info/github/rack/rack/master/file/SPEC).\n\n### Hello World example\n\nCreate a file called `app.rb`:\n\n```ruby\nrequire 'hobbit'\n\nclass App \u003c Hobbit::Base\n  get '/' do\n    'Hello World!'\n  end\nend\n```\n\nCreate a `config.ru` file:\n\n```ruby\nrequire './app'\n\nrun App.new # or just `run App`\n```\n\nRun it with `rackup`:\n\n```bash\n$ rackup\n```\n\nView your app at [http://localhost:9292](http://localhost:9292).\n\n### Routes\n\nEvery route is composed of a verb, a path (optional) and a block. When an\nincoming request matches a route, the block is executed and a response is sent\nback to the client. The return value of the block will be the `body` of the\nresponse. The `headers` and `status code` of the response will be calculated by\n`Hobbit::Response`, but you could modify it anyway you want it.\n\nSee an example:\n\n```ruby\nclass App \u003c Hobbit::Base\n  get '/' do\n    # ...\n  end\n\n  post '/' do\n    # ...\n  end\n\n  put '/' do\n    # ...\n  end\n\n  patch '/' do\n    # ...\n  end\n\n  delete '/' do\n    # ...\n  end\n\n  options '/' do\n    # ...\n  end\nend\n```\n\nWhen a route gets called you have this methods available:\n\n* `env`: The Rack environment.\n* `request`: a `Hobbit::Request` instance.\n* `response`: a `Hobbit::Response` instance.\n\nAnd any other method defined in your application.\n\n#### Available methods\n\n* `delete`\n* `get`\n* `head`\n* `options`\n* `patch`\n* `post`\n* `put`\n\n**Note**: Since most browsers don't support methods other than **GET** and\n**POST** you must use the `Rack::MethodOverride` middleware. (See\n[Rack::MethodOverride](https://github.com/rack/rack/blob/master/lib/rack/methodoverride.rb)).\n\n#### Routes with parameters\n\nBesides the standard `GET` and `POST` parameters, you can have routes with\nparameters:\n\n```ruby\nrequire 'hobbit'\n\nclass App \u003c Hobbit::Base\n  # matches both /hi/hobbit and /hi/patricio\n  get '/hi/:name' do\n    # request.params is filled with the route paramters, like this:\n    \"Hello #{request.params[:name]}\"\n  end\nend\n```\n\n#### Redirecting\n\nIf you look at Hobbit implementation, you may notice that there is no\n`redirect` method (or similar). This is because such functionality is provided\nby [Rack::Response](https://github.com/rack/rack/blob/master/lib/rack/response.rb)\nand for now we [don't wan't to repeat ourselves](http://en.wikipedia.org/wiki/Don't_repeat_yourself)\n(obviously you can create an extension!). So, if you want to redirect to\nanother route, do it like this:\n\n```ruby\nrequire 'hobbit'\n\nclass App \u003c Hobbit::Base\n  get '/' do\n    response.redirect '/hi'\n  end\n\n  get '/hi' do\n    'Hello World!'\n  end\nend\n```\n\n#### Halting\n\nTo immediately stop a request within route you can use `halt`. \n\n```ruby\nrequire 'hobbit'\n\nclass App \u003c Hobbit::Base\n  use Rack::Session::Cookie, secret: SecureRandom.hex(64)\n\n  def session\n    env['rack.session']\n  end\n\n  get '/' do\n    response.status = 401\n    halt response.finish\n  end\nend\n```\n\n### Built on top of rack\n\nEach Hobbit application is a Rack stack (See this\n[blog post](http://m.onkey.org/ruby-on-rack-2-the-builder) for more\ninformation).\n\n#### Mapping applications\n\nYou can mount any Rack application to the stack by using the `map` class\nmethod:\n\n```ruby\nrequire 'hobbit'\n\nclass InnerApp \u003c Hobbit::Base\n  # gets called when path_info = '/inner'\n  get do\n    'Hello InnerApp!'\n  end\nend\n\nclass App \u003c Hobbit::Base\n  map('/inner') { run InnerApp.new }\n\n  get '/' do\n    'Hello App!'\n  end\nend\n```\n\n#### Using middleware\n\nYou can add any Rack middleware to the stack by using the `use` class method:\n\n```ruby\nrequire 'hobbit'\n\nclass App \u003c Hobbit::Base\n  use Rack::Session::Cookie, secret: SecureRandom.hex(64)\n  use Rack::ShowExceptions\n\n  def session\n    env['rack.session']\n  end\n\n  get '/' do\n    session[:name] = 'hobbit'\n  end\n\n  # more routes...\nend\n\nrun App.new\n```\n\n### Security\n\nBy default, Hobbit (nor Rack) comes without any protection against web\nattacks. The use of [rack-protection](https://github.com/rkh/rack-protection)\nis highly recommended:\n\n```ruby\nrequire 'hobbit'\nrequire 'rack/protection'\nrequire 'securerandom'\n\nclass App \u003c Hobbit::Base\n  use Rack::Session::Cookie, secret: SecureRandom.hex(64)\n  use Rack::Protection\n\n  get '/' do\n    'Hello World!'\n  end\nend\n```\n\nSee the [rack-protection](https://github.com/rkh/rack-protection)\ndocumentation for futher information.\n\n### Testing\n\n[rack-test](https://github.com/brynary/rack-test) is highly recommended. See\nan example:\n\nIn `app.rb`:\n\n```ruby\nrequire 'hobbit'\n\nclass App \u003c Hobbit::Base\n  get '/' do\n    'Hello World!'\n  end\nend\n```\n\nIn `app_spec.rb`:\n\n```ruby\nrequire 'minitest/autorun'\n# imagine that app.rb and app_spec.rb are stored in the same directory\nrequire 'app'\n\ndescribe App do\n  include Rack::Test::Methods\n\n  def app\n    App.new\n  end\n\n  describe 'GET /' do\n    it 'must be ok' do\n      get '/'\n      last_response.must_be :ok?\n      last_response.body.must_match /Hello World!/\n    end\n  end\nend\n```\n\nSee the [rack-test](https://github.com/brynary/rack-test) documentation\nfor futher information.\n\n### Extensions\n\nYou can extend Hobbit by creating standard ruby modules. See an example:\n\n```ruby\nmodule MyExtension\n  def do_something\n    # do something\n  end\nend\n\nclass App \u003c Hobbit::Base\n  include MyExtension\n\n  get '/' do\n    do_something\n    'Hello World!'\n  end\nend\n```\n\n#### Hobbit::Contrib\n\n[hobbit-contrib](https://github.com/patriciomacadden/hobbit-contrib) is a ruby\ngem that comes with a lot of hobbit extensions, such as:\n\n* `Hobbit::Render`: provides basic template rendering.\n* `Hobbit::Session`: provides helper methods for handling user sessions.\n* `Hobbit::Environment`: provides helper methods for handling application\nenvironments.\n* `Hobbit::Filter`: provides helper class methods for handling Sinatra-like\nfilters.\n* `Hobbit::ErrorHandling`: provides helper class methods for handling\nSinatra-like error handling.\n\n... And many more!\n\n## Community\n\n* [Wiki](https://github.com/patriciomacadden/hobbit/wiki): Guides, how-tos and recipes\n* IRC: [#hobbitrb](irc://chat.freenode.net/#hobbitrb) on [http://freenode.net](http://freenode.net)\n\n## Presentations\n\n* Building web applications in Ruby, by [Krzysztof Wawer](https://github.com/wafcio)\n([english](https://speakerdeck.com/wafcio/hobbit-english), [polish](https://speakerdeck.com/wafcio/hobbit))\n\n## Contributing\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n\n## License\n\nSee the [LICENSE](https://github.com/patriciomacadden/hobbit/blob/master/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatriciomacadden%2Fhobbit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpatriciomacadden%2Fhobbit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatriciomacadden%2Fhobbit/lists"}