Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Auto-define your rack-apps in plaintext.
Ruby
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
example
lib
CHANGES.txt
LICENSE.txt Added docs to README
README.md
Rakefile
VERSION.yml
otto.gemspec

README.md

Otto - 0.4

Auto-define your rack-apps in plain-text.

Overview

Apps built with Otto have three, basic parts: a rackup file, a ruby file, and a routes file. If you've built a Rack app before, then you've seen a rackup file before. The ruby file is your actual app and the routes file is what Otto uses to map URI paths to a Ruby class and method.

A barebones app directory looks something like this:

$ cd myapp
$ ls
config.ru app.rb routes

See the examples/ directory for a working app.

Routes

The routes file is just a plain-text file which defines the end points of your application. Each route has three parts:

  • HTTP verb (GET, POST, PUT, DELETE or HEAD)
  • URI path
  • Ruby class and method to call

Here is an example:

GET   /                         App#index
POST  /                         App#receive_feedback
GET   /redirect                 App#redirect
GET   /robots.txt               App#robots_text
GET   /product/:prodid          App#display_product

# You can also define these handlers when no
# route can be found or there's a server error. (optional)
GET   /404                      App#not_found
GET   /500                      App#server_error

App

There is nothing special about the Ruby class. The only requirement is that the first two arguments to initialize be a Rack::Request object and a Rack::Response object. Otherwise, you can do anything you want. You're free to use any templating engine, any database mapper, etc. There is no magic.

class App
  attr_reader :req, :res

  # Otto creates an instance of this class for every request
  # and passess the Rack::Request and Rack::Response objects.
  def initialize req, res
    @req, @res = req, res
  end

  def index
    res.header['Content-Type'] = "text/html; charset=utf-8"
    lines = [
      '<img src="/img/otto.jpg" /><br/><br/>',
      'Send feedback:<br/>',
      '<form method="post"><input name="msg" /><input type="submit" /></form>',
      '<a href="/product/100">A product example</a>'
    ]
    res.body = lines.join($/)
  end

  def receive_feedback
    res.body = req.params.inspect
  end

  def redirect
    res.redirect '/robots.txt'
  end

  def robots_text
    res.header['Content-Type'] = "text/plain"
    rules = 'User-agent: *', 'Disallow: /private'
    res.body = rules.join($/)
  end

  def display_product
    res.header['Content-Type'] = "application/json; charset=utf-8"
    prodid = req.params[:prodid]
    res.body = '{"product":%s,"msg":"Hint: try another value"}' % [prodid]
  end

  def not_found
    res.status = 404
    res.body = "Item not found!"
  end

  def server_error
    res.status = 500
    res.body = "There was a server error!"
  end
end

Rackup

There is also nothing special about the rackup file. It just builds a Rack app using your routes file.

require 'otto'
require 'app'

app = Otto.new("./routes")

map('/') {
  run app
}

See the examples/ directory for a working app.

Installation

Get it in one of the following ways:

$ gem install otto
$ sudo gem install otto
$ git clone git://github.com/delano/otto.git

You can also download via tarball or zip.

More Information

In the wild

Services that use Otto:

Credits

Related Projects

License

See LICENSE.txt

Something went wrong with that request. Please try again.