Este é o primeiro de uma série de posts dedicado ao Rack. No início, Rack me parecia muito obscuro e estes posts serão criados com o intuito de clarear as idéias de quem ainda possui dificuldade para entender este pequeno framework.

Introdução da Introdução
Em fevereiro de 2007, Christian Neukirchen postou em seu blog um artigo chamado “Introduzindo Rack” no qual falava sobre a quantidade de código duplicado que ele achava em diferentes Frameworks Web escritos em Ruby. Ao anunciar a sua criação, o autor tocava em um ponto importante aonde escrevia, com razão, sobre um assunto que na verdade não era culpa dos desenvolvedores.
Sendo todos frameworks web, era de se esperar que muitas coisas fossem parecidas. A grande sacada do criador de Rack, foi o fato de ter percebido que web pode, em grande parte, ser resumida como uma série de requisições e respostas HTTP. O resto é framework que vai por cima.
HTTP pode ser resumido de maneira muito simples, como uma série de REQUESTS e RESPONSES. Rack utiliza-se muito bem dessa “simplicidade” para encapsular praticamente todo o controle dessa troca de mensagens em um objeto Ruby. Ao encapsular as requisições HTTP, Rack é capaz de prover interfaces para aplicações entre web servers, web frameworks e middlewares.
O que é Rack?
Podemos considerar o Rack uma especificação para a criação de aplicações web desenvolvidas com ruby. Segundo Dan Webb em sua apresentação “8 minutes on Rack“:
“Se você tem um objeto Ruby que possui um método call cujo o único argumento é env e retorna um array com 3 elementos ([200, {"Content-Type" => "text/html"}, "Hello World!"] ), então ele pode ser conectado a qualquer web server que suporte Rack”
Mas a definição mais simples possível é a que Rack provê uma interface mínima entre web servers e web frameworks escritos em Ruby.
Essa definição é interessante, mas Rack nos proporciona mais que isso. Com seu Builder (que será explorado em um post mais adiante) é possível integrar e ordenar módulos (ou middlewares) empilhados formando uma aplicação com os recursos desde módulos agrupados.

Por que usar Rack?
Oferece controle de requisições, sessões e cookies automaticamente.
Como Rack é uma especificação, desenvolvedores podem criar códigos que funcionam em qualquer aplicação e compartilhar módulos para uso de outros desenvolvedores. Dessa idéia já surgiu o rack-contrib, uma coleção de Midlewares e ferramentas disponível para que qualquer um utilize em sua aplicação.
Desenvolva middlewares que funcionam com Rails, Sinatra, Ramaze…
Qualquer servidor web que ofereça suporte a Rack rodará sua aplicação normalmente. Além disso, ela poderá ser transferida e replicada em servidores diferentes sem a necessidade de configurações diferentes.
A lista de servidores que já suportam Rack é grande. Até agora, os seguintes já suportam:
- Mongrel
- EventedMongrel
- SwiftipliedMongrel
- WEBrick
- FCGI
- CGI
- SCGI
- LiteSpeed
- Thin
- Ebb
- Fuzed
- Phusion Passenger
- Unicorn
Além dos servidores, praticamente todos os frameworks web desenvolvidos em Ruby já possuem adaptadores para Rack. A lista atual inclui os seguintes frameworks:
- Camping
- Coset
- Halcyon
- Mack
- Maveric
- Merb
- Racktools::SimpleApplication
- Ramaze
- Ruby on Rails
- Rum
- Sinatra
- Sin
- Vintage
- Waves
- Wee
Um exemplo minúsculo
O Rack possui uma ferramenta chamada rackup, que roda arquivos do tipo .ru. Neste exemplo, crie um arquivo chamado hello.ru e digite a seguinte linha:
run Proc.new {|env| [200, {"Content-Type" => "text/html"}, "Hello Horld!"]}
Agora rode o arquivo via linha de comando usando rackup:
> rackup hello.ru
E acesse o seguinte endereço em seu browser: http://localhost:8765/.
Pronto, você acabou de criar a página web no com o menor número de caracteres possível!
Um segundo exemplo um pouco maior
require 'rubygems'
require 'rack'
class HelloWorld
def call(env)
[200, {"Content-Type" => "text/html"}, "Hello Horld!"]
end
end
Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292
Apesar de sua função ser a mesma do anterior, este exemplo merece ser explicado. Como todo objeto Rack, nosso exemplo responde a um método call, retornando um array com os três elementos principais do Rack (que serão explicados no próximo post). Após definirmos esse simples método na nossa classe, basta instanciarmos um servidor (Mongrel nesse caso) que receberá requisições por uma porta (9292) e retornará o conteúdo do terceiro objeto do array do método call.
Se esse início já clareou um pouco mais as idéias sobre o Rack, fique ligado para os posts que seguirão a série para saber mais sobre Middlewares, Rails Metal, Builders e todos os outros elementos do maravilhoso mundo ro Rack!
Putz que legal, achei muito interessante eu ouvi falar de Rack e sempre tinha essa puga na atrás da orelha sobre middlewares. Tenho uma cadeira na faculdade que é “Sistemas Integrados” e agora posso compreender melhor o que o Rack faz. Parabéns pelo post, sigo acompanhando.
Simplesmente AWESOME!
Muito legal seu artigo. Até então eu só tinha ouvido falar do rack, agora até empolguei pra pesquisar mais a fundo.
Valeu pelos comentários pessoal! O segundo post já está quase pronto pra eu publicar.
Instalei o ruby. É a primeira vez que estou usando. Se o “rail -v”, no fim da instalação, não é mais acionado, como acionar o rack?