Sumário


Introdução

O que é Sinatra?

Sinatra é uma linguagem de domínio específico (DSL - Domain Specific Language) para a criação rápida de aplicações web escritas em ruby.

Ele mantém uma característica mínima definida, deixando livre o desenvolvedor para utilizar as ferramentas que melhor lhe servir em sua aplicação.

Ele não exige muito sobre sua aplicação, apenas que:

Em Sinatra, você pode escrever pequenas ad hoc aplicações ou maduras e grandes aplicações coma a mesma facilidade. (Veja a seção “Aplicações do mundo real” depois neste livro.)

Você pode utilizar o poder de varias Rubygems e outras bibliotecas para Ruby disponíveis.

Sinatra realmente se destaca quando você utiliza-o para experimentos e aplicações mock-ups ou para criar uma rápida interface para o seu código.

Este não é um framework Model-View-Controller, mas controles especificos de URL que direciona para código Ruby relevante que retorna resultados como resposta. Isto irá habilitar você a escrever códigos limpos, com aplicações devidamente organizadas: separando as views do código da aplicação, por exemplo.

Instalação

A maneira mais simples de se obter o Sinatra é através da rubygems

$ sudo gem install sinatra

Dependências

Sinatra depende da gem Rack (http://rack.rubyforge.org).

Para obter uma melhor experiência no uso você pode também instalar as gems Haml (http://haml.hamptoncatlin.com) e Builder (http://builder.rubyforge.org), que simplificarão os trabalhos com as views.

$ sudo gem install builder haml

Vivendo com as novidades

As últimas novidades do Sinatra estão no Github, disponível em http://github.com/sinatra/sinatra/tree/master.

Você também pode utilizar a última versão para contribuir com novas funcionalidades para o framework.

Siga os seguintes passos:

  1. cd local/do/seu/projeto
  2. git clone git://github.com/sinatra/sinatra.git
  3. cd sinatra
  4. cd seu_projeto
  5. ln -s ../sinatra

E para utilizar isto basta adicionar a seguinte linha no arquivo da sua aplicação:

$:.unshift File.dirname(__FILE__) + '/sinatra/lib'
require 'sinatra'

Você pode verificar qual a versão que a aplicação esta utilizando adicionando a seguinte rota:

get '/versao' do
  "Versão utilizada: " + Sinatra::VERSION
end

para verificar o resultado acesse http://localhost:4567/versao.

Aplicação “Hello Word”

O Sinatra já está instalado e você esta pronto para experimentá-lo, que tal construir sua primeira aplicação?

# hello_world.rb
require 'rubygems'
require 'sinatra'

get '/' do
  "Olá Mundo, agora é #{Time.now} no servidor!"
end

Rode isto com o seguinte comando $ ruby myapp.rb e visualize o resultado em http://localhost:4567

Aplicações do mundo real com Sinatra

Github Services

Git hosting disponibilizado pelo Github utiliza Sinatra para post-receive hooks, chamando os serviços/URLs especificas do usuário, sempre que alguém envia algo para os repositórios:

Git Wiki

Git Wiki é um mecanismo minimo de Wiki desenvolvido com Sinatra e Git. Veja também os diversos forks com funcionalidades adicionais.

Integrity

Integrity é um serviço pequeno e limpo de integração continua utilizando Sinatra, detectando falhas em builds de seu codebase e notificando você através de difersos canais de comunicação.

Seinfeld Calendar

Seinfeld Calendar é uma divertida aplicação para monitorar as suas contribuições em projetos open-source, mostrando seus “streaks”, ou seja seus commits em seus repositórios do Github.

Sobre este livro

Este livro assume que você já tem um conhecimento básico da linguagem Ruby e sabe como funciona o interpretador Ruby.

Para maiores informações sobre a linguagem Ruby visite os seguintes links:


Rotas

métodos http

As rotas do Sinatra foram concebidas para responder a métodos de requisições HTTP.

básico

Simples

get '/hi' do
  ...
end

Com parâmetros

get '/:name' do
  # matches /sinatra and the like and sets params[:name]
end

opções

em breve

splats

get '/say/*/to/*' do
  # matches /say/hello/to/world
  params["splat"] # => ["hello", "world"]
end

get '/download/*.*' do
  # matches /download/path/to/file.xml
  params["splat"] # => ["path/to/file", "xml"]
end

user agent

get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
  "You're using Songbird version #{params[:agent][0]}"
end

get '/foo' do
  # matches non-songbird browsers
end

outros métodos

Os outros métodos são requisitados exatamente da mesma forma como uma rota “get”. Você simplesmente usa o “post”, “put” ou “delete” que já estarão definidos como uma rota, além do “get” é claro. Para acessar os parâmetros POSTados, use params[:xxx] onde xxx é nome do elemento postado pelo seu formulário.

post '/foo' do
  "você requisitou por foo, com o parâmetro bar via post igual a #{params[:bar]}"
end

os métodos PUT e DELETE

Quando os browsers não suportavam nativamente os métodos PUT e DELETE, alguns hacks ou workaround eram adotados pela comunidade web. Bastava adicionar um elemento hidden com o nome “metodo” e o valor igual ao método HTTP que você desejava usar. O formulário continuará sendo enviado como um POST, porém o Sinatra irá interpretá-lo com o método desejado.

Quando você quiser usar PUT ou DELETE em um formulário com um browser que não tem suporte (da mesma forma como Curl ou ActiveResorce), simplesmente vá em frente e use-os normalmente, ignorando aquele método citado acima. Aquilo é apenas para “hackear” um suporte aos browsers.

como as rotas são requisitadas

Cada vez que você adiciona uma nova rota na sua aplicação, é compilada uma nova expressão regular para verifica-lá. Isto é guardado em um array através de um handler que adiciona um bloco de código para cada rota.

Quando é feita uma nova requisição, ela passa pela expressão regular que roda para verifica-lá. Então o handler (bloco de código) anexado para a rota é executado.


Handlers

Estrutura

Handler é um termo genérico utilizado pelo Sinatra para “controllers”. Um handler é o ponto inicial de entrada para uma nova requisição http em sua aplicação.

Para saber mais sobre rotas, leia o capitúlo Rotas (logo acima deste)

redirect

O helper redirect é um atalho para o código (302) de resposta http comum.

Basicamente é muito fácil:

redirect '/'

redirect '/posts/1'

redirect 'http://www.google.com'

Atualmente o redirect envia de volta para o browser um Location header e o browser faz a requisição seguinte para o local indicado. Desde que o browser faça a requisição seguinte você poderá redirecionar para outra página em sua aplicação ou totalmente para um outro site.

O fluxo de requests durante um redirect é:

Browser –> Server (redirect to ’/’) –> Browser (request ’/’) –> Server (result for ’/’)

Sinatra envia por padrão o código de resposta 302. Segundo o spec, 302 não pode alterar o método de requisição, mas você vê uma nota na maioria dos browsers dizendo que irão mudar isto. Aparentemente os browsers mobile que as pessoas estão usando fazem as coisas corretamente ( ao invés de seguir má interpretação da maioria ).

A solução para isso no spec é enviar 2 diferentes códigos de resposta: 303 e 307. 303 reinicia o GET, 307 mantém o mesmo método.

Para forçar o sinatra a enviar um código de resposta diferente, é muito simples:

redirect '/', 303 # força o retorno do código 303

redirect '/', 307 # força o retorno do código 307

sessões

Sinatra possui um suporte básico para cookie baseado em sessão. Para habilitar isso, no bloco de configuração ou no inicio da sua aplicação, você precisará habilitar a seguinte opção:

enable :sessions

A desvantagem desta abordagem com sessão é que todos os dados serão armazenados no cookie. Cookies sempre terão um limite de 4 kilobytes, você nao poderá armazenar muitos dados. Outra questão é que cookies não são invioláveis. O usuário poderá modificar quaisquer dados na sua sessão. Mas…. por ser muito fácil, não terá problemas tendo de escalar memória ou banco de dados para rodar de backend junto com a sessão.

Memória baseada em sessões

em breve

Memcached baseado em sessões

em breve

Arquivos baseados em sessões

em breve

Banco de dados baseados em sessões

em breve

cookies

Cookies são bastante simples de se usar no Sinatra, porém com algumas ressalvas.

Vamos primeiro olhar um simples caso de uso:

require 'sinatra'

get '/' do
    # Get the string representation
    cookie = request.cookies["thing"]

    # Set a default
    cookie ||= 0

    # Convert to an integer
    cookie = cookie.to_i

    # Do something with the value
    cookie += 1

    # Reset the cookie
    set_cookie("thing", cookie)

    # Render something
    "Thing is now: #{cookie}"
end

Definir um diretório, data de expiração ou domínio requer um pouco mais de complicação - veja o código-fonte do set_cookie se você quiser ir mais a fundo.

set_cookie("thing", { :domain => myDomain,
                      :path => myPath,
                      :expires => Date.new } )

Estas são as coisas mais simples com cookies - Você pode também serializar um objeto de Arrays, separando com “e” comercial (&), mas quando obter de volta, terá que desserializar e dividi-lo de qualquer forma, uma grande mão de obra, codificando uma string e depois parseando-a para o seu prazer.

status

Se você deseja definir seu próprio status para resposta ao invés do convencional 200 (Successo), você pode usar o helper status- para definir o código, e ainda assim renderizar normalmente:

get '/' do
  status 404
  "Não funciona"
end

Alternativamente você pode usar throw :halt, [404, "Not found"] para imediatamente parar futuras ações e retornar o código de status especificado e uma string para o cliente. throw suportam mais opções a respeito disto, consulte o capítulo adequado para maiores informações.

autenticação

em breve


Filtros

before do…

Este filtro é executado em Sinatra::EventContext

before do

.. este código será executado antes de cada evento ..

end

Manipulação de parametrôs aninhados ao estilo Rails

Se você quiser usar um formulário com parametrôs ao estilo deste (aka. Rails’ nested params)

	<form>
	  <input ... name="post[title]" />
	  <input ... name="post[body]" />
	  <input ... name="post[author]" />
	</form>

Você deve converter os parametros para um hash. Você pode fazer isso facilmente usando o filtro “before”:

	before do
	 new_params = {}
	 params.each_pair do |full_key, value|
		 this_param = new_params
		 split_keys = full_key.split(/\]\[|\]|\[/)
		 split_keys.each_index do |index|
			 break if split_keys.length == index + 1
			 this_param[split_keys[index]] ||= {}
			 this_param = this_param[split_keys[index]]
		 end
		 this_param[split_keys.last] = value
	 end
	 request.params.replace new_params
	end

Para então se tornarem nos seguintes paramêtros:

{“post”=>{ “title”=>”“, “body”=>”“, “author”=>”” }}


Views

Todos arquivos-base serão localizados na seguinte estrutura:

root
  | - views/

Linguagens de Template

Haml

get '/' do
  haml :index
end

Isto irá renderizar ./views/index.haml

Sass

get '/' do
  sass :styles
end

Isto irá renderizar ./views/styles.sass

Erb

get '/' do
  erb :index
end

Isto irá renderizar ./views/index.erb

Builder

get '/' do
  builder :index
end

Isto irá renderizar ./views/index.builder

get '/' do
  builder do |xml|
    xml.node do
      xml.subnode "Texto interno"
    end
  end
end

Isto irá renderizar o xml inline, diretamente do handler.

Atom Feed

em breve

RSS Feed

Suponhamos que a url do site seja http://liftoff.msfc.nasa.gov/.

	get '/rss.xml' do
	  builder do |xml|
	    xml.instruct! :xml, :version => '1.0'
	    xml.rss :version => "2.0" do
	      xml.channel do
		xml.title "Liftoff News"
		xml.description "Liftoff to Space Exploration."
		xml.link "http://liftoff.msfc.nasa.gov/"

		@posts.each do |post|
		  xml.item do
		    xml.title post.title
		    xml.link "http://liftoff.msfc.nasa.gov/posts/#{post.id}"
		    xml.description post.body
		    xml.pubDate Time.parse(post.created_at.to_s).rfc822()
		    xml.guid "http://liftoff.msfc.nasa.gov/posts/#{post.id}"
		  end
		end
	      end
	    end
	  end
	end

Isso irá renderizar o rss inline, diretamente no handler.

Layouts

Layouts são muito simples no Sinatra. Crie um arquivo em seu diretório de views nomeado como “layout.erb”, “layout.haml” ou “layout.builder”. Quando a página renderizar, o layout apropriado será invocado (do mesmo tipo de arquivo) e usado.

O layout pode ter no seu contexto um ponto onde será realizada uma chamada para incluir outros conteúdos.

Um exemplo de um layout com haml seria um arquivo parecido com este:

%html
  %head
    %title SINATRA BOOK
  %body
    #container
      = yield

evitando um layout

Algumas vezes você deseja que o layout não seja renderizado. No seu método de renderização simplesmente passe :layout => false e você será o cara.

get '/' do
  haml :index, :layout => false
end

No arquivo das Views

Isto é uma fria:

get '/' do
  haml :index
end

use_in_file_templates!

__END__

@@ layout
X
= yield
X

@@ index
%div.title Olá Mundo!!!!!

Experimente!

Partials

em breve


Models

Datamapper

em breve

Sequel

em breve

ActiveRecord

Primeiro você deverá incluir a gem ActiveRecord na sua aplicação, em seguida definir os dados de conexão ao banco de dados:

	require 'rubygems'
	require 'sinatra'
	require 'activerecord'

	ActiveRecord::Base.establish_connection(
	  :adapter => 'sqlite3',
	  :dbfile =>  'sinatra_application.sqlite3.db'
	)

Agora você pode criar e usar modelos com o ActiveRecord assim como no Rails (o exemplo pressupõe que você já tem uma tabela ‘posts’ no seu banco de dados)

	class Post < ActiveRecord::Base
	end

	get '/' do
	  @posts = Post.all()
	  erb :index
	end

Para renderizar isso em ./views/index.html:

	<% for post in @posts %>
	  <h1><% post.title %></h1>
	<% end %>

Helpers

O básico

Não é aconselhável que você crie helpers na raiz da sua aplicação. Eles distorcem o namespace global e não têm um fácil acesso aos requests, reponse, session ou cookies.

Em vez disso, use o prático método Sinatra::EventContenxt para instalar helpers para o uso dentro de eventos e templates.

Exemplo:

helpers do
  def bar(name)
    "#{name}bar"
  end
end


get '/:name' do
  bar(params[:name])
end

implementando partials no estilo rails

Usar partials em suas views é uma ótima maneira de mante-las limpas. Para que Sinatra possa se aproximar do design de um framework, você terá que implementar um handler de partial nele próprio.

Eis aqui uma versão realmente básica:

# Usage: partial :foo
helpers do
  def partial(page, options={})
      haml page, options.merge!(:layout => false)
  end
end

Uma versão mais avançada desse handler passando variaveis locais e interando um hash seria algo parecido com isto:

# Render the page once:
# Usage: partial :foo
#
# foo will be rendered once for each element in the array, passing in a local variable named "foo"
# Usage: partial :foo, :collection => @my_foos

helpers do
  def partial(template, *args)
    options = args.extract_options!
    options.merge!(:layout => false)
    if collection = options.delete(:collection) then
      collection.inject([]) do |buffer, member|
        buffer << haml(template, options.merge(
                                  :layout => false,
                                  :locals => {template.to_sym => member}
                                )
                     )
      end.join("\n")
    else
      haml(template, options)
    end
  end
end

Rack Middleware

Sinatra pode rodar sob Rack, um padrão mínimo de interface para frameworks web escritos em Ruby. Uma das capacidades mais interessantes do Rack é a de se poder desenvolver uma aplicação sob um “middleware” — componente localizado entre o servidor e sua aplicação monitorando e/ou manipulando requisições/respostas HTTP fornecendo várias funcionalidades em comuns.

Sinatra faz a utilização de um canal Rack middleware através do uso muito fácil de um método de alto nível:

require 'sinatra'
require 'my_custom_middleware'

use Rack::Lint
use MyCustomMiddleware

get '/hello' do
    'Hello World'
end

A semântica de utilização é idêntica a definida para o Rack:: Construtor DSL (mais frequentemente utilizado a partir do arquivo rackup). Como por exemplo, ao utilizar um método que aceita múltiplos/variáveis argumentos da mesma forma como os blocos:

use Rack::Auth::Basic do |username, password|
   username == 'admin' && password == 'secreto'
end

Rack é distribuída com uma variedade de middleware padrões para login, debug, URL routing, autenticação e manipulação de sessões. Sinatra usa muito desses componentes automaticamente baseado na configuração de modo que você normalmente não tenha que usá-los explicitamente.


Error Handling

not_found

Lembre-se: Isto irá rodar sob o Sinatra::EventContext que significa que você poderá te-lo em todos os bons formatos que lhe são oferecidos (i.e. haml, erb, :halt, etc.)

Sempre que uma NotFound é levantadas ela é tratada pela seguinte chamada

not_found do
  'Isto esta longe de ser encontrado'
end

erros

Por default os erros são capturados por Sinatra::ServerError

O Sinatra irá enviar seu erro através do ‘sinatra.error’ no request.env

error do
  'Desculpe mas houve um erro desagradável - ' + request.env['sinatra.error'].name
end

Customizando o error mapping:

error MyCustomError do
  'O que acabou de acontecer foi...' + request.env['sinatra.error'].message
end

se isto acontecer:

get '/' do
  raise MyCustomError, 'algo terrível'
end

você irá obter isto:

O que acabou de acontecer foi... algo terrível

Informações Adicionais

Com Sinatra você pode tornar o padrão de error e not_found mais seguro em :production. Se você deseja customizar apenas para :production com uma tela mais amigável do que em :development então faça o seguinte:

configure :production do

  not_found do
    "Desculpe-nos, mas isto não esta funcionando"
  end

  error do
    "Algo realmente desagradável aconteceu.  Estamos trabalhando nisto!"
  end

end

Halt!

Para interromper imediatamente um request durante ou antes com um filtro ou na utilização de um evento:

throw :halt

Para definir o corpo do resultado com um método helper:

throw :halt, :helper_method

Define o corpo do resultado com um método helper enviando depois com os parametros do escopo local

throw :halt, [:helper_method, foo, bar]

Para definir o corpo do resultado com uma string:

throw :halt, 'Isto será a mensagem!'

Para definir um status e depois o corpo da mensagem:

throw :halt, [401, 'vá embora!']

Define o status e então chama o método helper com os parametros do escopo local

throw :halt, [401, [:helper_method, foo, bar]]

Roda uma proc na instancia de Sinatra:EventContext e define o corpo do resultado

throw :halt, lambda { puts 'Na proc!'; 'Eu escrevi ao $stdout!' }

Crie seu próprio “toresult”

class MyResultObject
	def to_result(event_context, *args)
		event_context.body = 'Isto será a mensagem!'
	end
end

get '/' do
	throw :halt, MyResultObject.new
end

Configuração

Use as opções “set” do Sinatra

Blocos de configuração não são executados no contexto dos eventos e não possuem acesso as variaveis de instância. Para guardar um pedaço de informação que você queira acessar nas suas rotas, utilize set.

configure :development do
  set :dbname, 'devdb'
end

configure :production do
  set :dbname, 'productiondb'
end

get '/qualbanco' do
  'Você esta utilizando o banco de dados ' + options.dbname
end

Arquivo de configuração externa através do bloco de configuração

em breve

Módulo da aplicação / Área de configuração

em breve


Deployment

Lighttpd Proxied to Thin

Iremos cobrir aqui como realizar o deploy no Sinatra com suporte a proxy reverso e load balancing utilizando Lighttpd e Thin.

  1. Instalando Lighttpd e Thin

     # Verifique se você já tem lighttpd, isto pode ser verificado através do gerenciado de pacotes da sua distribuição Linux
    
     # Para o Thin:
     gem install thin
  2. Crie seu arquivo de rackup - é necessario que tenha a linha “require ‘app’“, equivalente a sua aplicação Sinatra.

     require 'app'
    
     set :env,       :production
     set :port,      4567
     disable :run, :reload
    
     run Sinatra.application
  3. Configure o config.yml - mude o /local/da/minha/app para o diretório correto da sua aplicação.

     ---
         environment: production
         chdir: /local/da/minha/app
         address: 127.0.0.1
         user: root
         group: root
         port: 4567
         pid: /local/da/minha/app/thin.pid
         rackup: /local/da/minha/app/config.ru
         log: /local/da/minha/app/thin.log
         max_conns: 1024
         timeout: 30
         max_persistent_conns: 512
         daemonize: true
  4. Configure o lighttpd.conf - troque “mydomain” pelo edereço correto. Também marque corretamente a porta primária conforme configurado no config.yml.

      $HTTP["host"] =~ "(www\.)?mydomain\.com"  {
              proxy.balance = "fair"
              proxy.server =  ("/" =>
                                      (
                                              ( "host" => "127.0.0.1", "port" => 4567 ),
                                              ( "host" => "127.0.0.1", "port" => 4568 )
                                      )
                              )
      }
  5. Inicie o thin e a sua aplicação. Eu criei um script que já faz isso chamado de “rake start”.

      thin -s 2 -C config.yml -R config.ru start

Esta feito! Va até o seu dominio “mydomain.com/” e veja o resultado! Tudo pode ser configurado agora, verifique também a configuração do seu dominio no seu arquivo lighttpd.conf.

Variações - nginx via proxy - O mesmo acesso do proxy pode ser aplicado ao web server nginx

upstream www_mydomain_com {
	server 127.0.0.1:5000;
	server 127.0.0.1:5001;
}

server {
	listen		www.mydomain.com:80
	server_name	www.mydomain.com live;
	access_log /path/to/logfile.log

	location / {
		proxy_pass http://www_mydomain_com;
	}

}

Variações - Mais instâncias Thin - Para adicionar mais instâncias thin, mude o paramêtro -s 2 no comando de inicialização do thin para a quantos servidores você deseja. E não se esqueça dos proxies lighttpd, adicionando uma nova linha para cada um deles. Após, reinicie o lighttpd e tudo irá subir conforme o esperado.

Passenger (mod rails)

Odeia fazer deployment com FastCGI? Você não esta sozinho. Pois advinhe só, Passenger tem suporte a Rack; e este livro irá lhe dizer como fazer tudo isso.

Você pode encontrar documentação adicional sobre Passenger no seu repositório no Github.

  1. Configurando através da interface de conta na Dreamhost

     Domains -> Manage Domains -> Edit (web hosting column)
     Habilite 'Ruby on Rails Passenger (mod_rails)'
     Adicione o diretório "public" no campo para diretórios web. Caso você estiver usando 'rails.com', isto irá mudar para 'rails.com/public'
     Salve suas alterações
  2. Criando a estrutura de diretórios

     domain.com/
     domain.com/tmp
     domain.com/public
     # local para uma versão do sinatra - não necessário caso estiver usando gems
     domain.com/sinatra
  3. Criando o arquivo de “Rackup” (rack configuration file) config.ru

    # Este arquivo irá ficar em domain.com/config.ru
    require 'sinatra/lib/sinatra.rb'   # "require 'sinatra'" caso tiver sido instalado via gems
    require 'rubygems'
    
    require 'test.rb' # assuma que o arquivo da sua aplicação Sinatra seja 'test.rb'
    
    set :env,  :production
    disable :run
    
    run Sinatra.application
  4. Uma aplicação Sinatra bastante simples

     # este é o arquivo test.rb citado acima
     get '/' do
             "Trabalhando na dreamhost"
     end
    
     get '/foo/:bar' do
             "Você requisitou por foo/#{params[:bar]}"
     end

E isso é tudo que necessitamos por enquanto! Uma vez tudo configurado, acesse seu dominio e você já poderá ver a página “Trabalhando na dreamhost”. Para reiniciar a aplicação após algumas mudanças, você precisará executar touch tmp/restart.txt.

Observe que na versão atual do passenger (2.0.3) existe um bug onde o Sinatra não encontra o diretório das views. Neste caso, adicione a opção :views => '/diretório/das/views/' no seu arquivo Rackup do Sinatra.

Nota complementar: algumas documentações terão um formato diferente de passar as opções no arquivo Rackup do Sinatra, como por exemplo:

	Sinatra::Application.default_options.merge!(
	  :run => false,
	  :env => :production,
	  :raise_errors => true
	)

FastCGI

O método padrão para fazer deployment é usando Thin ou Mongrel, e ter um proxy reverso (lighttpd, nginx ou mesmo Apache) apontando para o seus servidores.

Mas nem sempre isto é possível. Em hosts baratos e compartilhados (como Dreamhost) você não pode ter rodando Thin ou Mongrel, ou configurar proxy reverso (pelo menos no plano padrão compartilhado).

Felizmente, Rack suporta varias conexões, incluindo CGI e FastCGI. Infelizmente para nós, FastCGI não trabalha muito bem com a versão atual do Sinatra.

Para enviar um simples ‘hello world’ com uma aplicação Sinatra rodando na Dreamhost é necessário baixar todo o código atual do Sinatra, e hackear ele um pouco. Não se preocupe, isto somente requer comentar algumas linhas e ajustar algumas outras.

Passos para um deploy com FastCGI:

  1. .htaccess RewriteEngine on

     AddHandler fastcgi-script .fcgi
     Options +FollowSymLinks +ExecCGI
    
     RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
  2. dispatch.fcgi #!/usr/bin/ruby

     require 'sinatra/lib/sinatra.rb'
     require 'rubygems'
    
     fastcgi_log = File.open("fastcgi.log", "a")
     STDOUT.reopen fastcgi_log
     STDERR.reopen fastcgi_log
     STDOUT.sync = true
    
     set :logging, false
     set :server, "FastCGI"
    
     module Rack
       class Request
         def path_info
           @env["REDIRECT_URL"].to_s
         end
         def path_info=(s)
           @env["REDIRECT_URL"] = s.to_s
         end
       end
     end
    
     load 'test.rb'
  3. sinatra.rb - Modificar esta função com uma nova versão aqui (descomentando as linhas puts)

     def run
       begin
         #puts "== Sinatra começou os trabalhos na porta #{port} para #{env} apoiado pelo #{server.name}"
         require 'pp'
         server.run(application) do |server|
           trap(:INT) do
             server.stop
             #puts "\n== Sinatra já terminou sua configuração (e a multidão aplaude)"
           end
         end
       rescue Errno::EADDRINUSE => e
         #puts "== Algo já está sendo executando na porta #{port}!"
       end
     end

Heroku

Heroku já tem um suporte basico para aplicações em Sinatra. Esta é provavelmente a opção mais fácil de deployment desde que configurada corretamente, deploying no heroku torna-se basicamente uma questão de um simples git push.

Passos para deploy no Heroku:

  1. um exemplo de arquivo rackup:

     require File.dirname(__FILE__) + "/../my_sinatra_app"
    
     set     :app_file, File.expand_path(File.dirname(__FILE__) + '/../my_sinatra_app.rb')
     set     :public,   File.expand_path(File.dirname(__FILE__) + '/../public')
     set     :views,    File.expand_path(File.dirname(__FILE__) + '/../views')
     set     :env,      :production
     disable :run,      :reload
    
     run Sinatra.application
  2. git push

     $ git remote add heroku git@heroku.com:my-sinatra-app.git
     $ git push heroku master

Fuzed e Amazon

// TODO: Conversar com o Blake sobre isso

Poolparty e Amazon EC2

// TODO: Quais outras estratégias de deployment são usadas lá?


Contribuindo

Como eu posso clonar o repositório do Sinatra?

Antes de tudo, você precisará usar Git como seu sistema de controle de versão. Git está disponível para todas as principais plataformas:

Após isso, clonar o repositório do Sinatra será muito fácil bastando digitar a seguinte linha em sua linha de comando:

git clone git://github.com/bmizerany/sinatra.git

Como criar um patch?

em breve

Como enviar um path para o repositório oficial do Sinatra?

em breve



Sobre a tradução

Esta é uma tradução livre para o português realizada por Tailor R. Fontela, se você encontrar algum erro ou quiser colaborar com a evolução do projeto adicionando mais conteúdo faça um fork do projeto no Github.

Você pode acompanhar as atualizações e evolução deste projeto através do RSS.