<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ruby Vault &#187; Rack</title>
	<atom:link href="http://www.tbueno.com/blog/category/rack/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tbueno.com/blog</link>
	<description>Explorando o maravilhoso mundo de Ruby</description>
	<lastBuildDate>Tue, 24 Aug 2010 03:02:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>RS on Rails 2010</title>
		<link>http://www.tbueno.com/blog/sinatra/2010/08/rs-on-rails-2010/</link>
		<comments>http://www.tbueno.com/blog/sinatra/2010/08/rs-on-rails-2010/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 03:02:44 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[Rack]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Sinatra]]></category>
		<category><![CDATA[Eventos]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=332</guid>
		<description><![CDATA[O RS on Rails desse ano foi um sucesso absoluto. Auditório com ótima ocupação, palestras inspiradas e lightning talks interessantes marcaram esta segunda edição do evento. Deixo aqui meus agradecimentos aos organizadores e ao público presente. Abaixo, segue minha apresentação sobre aplicações Rack. Aplicações Rack &#8211; RS on Rails 2010 View more presentations from thibusil.]]></description>
			<content:encoded><![CDATA[<p>O <a href="http://www.rsrails.com.br/">RS on Rails</a> desse ano foi um sucesso absoluto. Auditório com ótima ocupação, palestras inspiradas e <em>lightning talks</em> interessantes marcaram esta segunda edição do evento.</p>
<p>Deixo aqui meus agradecimentos aos organizadores e ao público presente. Abaixo, segue minha apresentação sobre aplicações Rack.</p>
<div style="width:425px" id="__ss_5042732"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/thibusil/rack-rs-on-rails" title="Aplicações Rack - RS on Rails 2010">Aplicações Rack &#8211; RS on Rails 2010</a></strong><object id="__sse5042732" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rack-rsonrails-100823210931-phpapp02&#038;stripped_title=rack-rs-on-rails" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse5042732" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rack-rsonrails-100823210931-phpapp02&#038;stripped_title=rack-rs-on-rails" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/thibusil">thibusil</a>.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/sinatra/2010/08/rs-on-rails-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Superguia Rack &#8211; Parte 3 &#8211; Middlewares</title>
		<link>http://www.tbueno.com/blog/rack/2009/10/superguia-rack-parte-3-middlewares/</link>
		<comments>http://www.tbueno.com/blog/rack/2009/10/superguia-rack-parte-3-middlewares/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 18:40:24 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[Rack]]></category>
		<category><![CDATA[Midlewares]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=295</guid>
		<description><![CDATA[Se você quer entender rapidamente o que é um Middleware, pense em um filtro. Algo que permite que todas as requisições e respostas passem por ele, permitindo assim, que ele altere-as como bem entender. Middlewares devem possuir o mesmo método call de qualquer outro objeto Rack, porém em seu construtor, eles devem receber outra aplicação [...]]]></description>
			<content:encoded><![CDATA[<p>Se você quer entender rapidamente o que é um Middleware, pense em um filtro. Algo que permite que todas as requisições e respostas passem por ele, permitindo assim, que ele altere-as como bem entender. Middlewares devem possuir o mesmo método <em>call</em> de qualquer outro objeto Rack, porém em seu construtor, eles devem receber outra aplicação como argumento. Esta é uma maneira simples de empilhar diversas aplicações. Se você vem de outras linguagens como Java ou C# e já leu sobre Design Patterns, deve estar reconhecendo o padrão Decorator. A idéia é  semelhante, mas com Ruby as coisas se tornam muito mais simples.</p>
<h2>Nosso primeiro middleware</h2>
<p>Se pegarmos o exemplo simples do HelloWorld apresentado no início desta sequência de posts sobre Rack, podemos acomplar um middleware a ele, adicionando funcionalidades extras à aplicação original.</p>
<p>Primeiros, vamos criar nosso Middleware. O exemplo é muito simples. Após imprimirmos um &#8220;Hello World!&#8221;, vamos informar a hora.</p>
<pre class="brush: ruby">
class Middleware
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)
    response_body = ""
    response.each { |part| response_body += part }
    response_body += " --- #{Time.now}"
    headers["Content-Length"] = response_body.length.to_s
    [status, headers, [response_body]]
  end
end
</pre>
<p>Não se assuste se você não entender tudo de cara. A parte mais complicada é cocatenar a informação de tempo na resposta, e isso é feito usando um each, devido ao fato de o response poder ser qualquer objeto que responda a esse método. Além disso, para que nossa resposta seja válida, é interessante colocar no cabeçalho HTTP o comprimento do nosso body.</p>
<p>Mas além do middleware, devemos dizer que nossa aplicação original quer usar ele. E isso deve ser feito em um arquivo .ru:</p>
<pre class="brush: ruby">
#config.ru
require 'rack'
require 'middleware'
require 'hello_world'      

use Middleware
run HelloWorld.new
</pre>
<p>Agora rodando &#8220;rackup config.ru&#8221; na linha de comando, teremos o seguinte no nosso servidor:</p>
<p><span id="more-295"></span><br />
Hello World! &#8212; 2009-10-05 14:05:58 -0300</p>
<h2>Outros Exemplos de Middlewares</h2>
<p>Na primeira parte dessa série de <a href="http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-1/#more-253">artigos</a>, citei o projeto <a href="http://github.com/rack/rack-contrib">rack-contrib</a>, que consistia em uma coleção de Middlewares criados pela comunidade e disponibilizado em um único projeto. Além de serem de extrema utilidade no desenvolvimento, eles também servem como um ótimo objeto de estudo para quem quer aprender sobre o funcionamento de um Middleware. Se olharmos o código do exemplo garbagecollection.rb, veremos que o funcionamento é extremamente simples, consistindo apenas de uma chamada forçada do Garbage Collector a cada request na aplicação.</p>
<pre class="brush: ruby">
module Rack
  # Forces garbage collection after each request.
  class GarbageCollector
    def initialize(app)
      @app = app
    end

    def call(env)
      @app.call(env)
    ensure
      GC.start
    end
  end
end
</pre>
<p>Sem entrar no mérito da utilidade do exemplo, é interessante notar a simplicidade do código. Em <a href="http://github.com/ambethia/rack-google_analytics">outro exemplo</a>, podemos ver integração fácil do código do Google Analytics em sua aplicação a com 2 linhas:</p>
<pre class="brush: ruby">
require "rack/google_analytics"
use Rack::GoogleAnalytics, :web_property_id => "UA-000000-1"
</pre>
<p>E o código, propriamente dito, é algo simples:</p>
<pre class="brush: ruby">
module Rack #:nodoc:
  class GoogleAnalytics < Struct.new :app, :options

    def call env
      status, headers, response = app.call(env)

      if headers["Content-Type"] =~ /text\/html|application\/xhtml\+xml/
        body = ""
        response.each { |part| body << part }
        index = body.rindex("</body>")
        if index
          body.insert(index, tracking_code(options[:web_property_id]))
          headers["Content-Length"] = body.length.to_s
          response = [body]
        end
      end

      [status, headers, response]
    end

    private

      # Returns JS to be embeded. This takes one argument, a Web Property ID
      # (aka UA number).
      def tracking_code web_property_id
        return <<-EOF
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("#{web_property_id}");
pageTracker._trackPageview();
} catch(err) {}</script>
EOF
      end

  end
end
</pre>
<p>Um outro exemplo interessante é o Middleware CommonLogger, incorporado ao código do projeto Rack. É uma implementação de logs para aplicações Rack, baseada no projeto <a href="http://commons.apache.org/logging/">Commons Logging da Apache</a> . Primeiro, vejamos o código para depois analisar-mos seu funcionamento.</p>
<pre class="brush: ruby">

module Rack
  # Rack::CommonLogger forwards every request to an +app+ given, and
  # logs a line in the Apache common log format to the +logger+, or
  # rack.errors by default.
  class CommonLogger
    # Common Log Format: http://httpd.apache.org/docs/1.3/logs.html#common
    # lilith.local - - [07/Aug/2006 23:58:02] "GET / HTTP/1.1" 500 -
    # %{%s - %s [%s] "%s %s%s %s" %d %s\n} %
    FORMAT = %{%s - %s [%s] "%s %s%s %s" %d %s %0.4f\n}

    def initialize(app, logger=nil)
      @app = app
      @logger = logger
    end

    def call(env)
      began_at = Time.now
      status, header, body = @app.call(env)
      log(env, status, header, began_at)
      [status, header, body]
    end

    private

    def log(env, status, header, began_at)
      now = Time.now
      length = extract_content_length(header)

      logger = @logger || env['rack.errors']
      logger.write FORMAT % [
        env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
        env["REMOTE_USER"] || "-",
        now.strftime("%d/%b/%Y %H:%M:%S"),
        env["REQUEST_METHOD"],
        env["PATH_INFO"],
        env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"],
        env["HTTP_VERSION"],
        status.to_s[0..3],
        length,
        now - began_at ]
    end

    def extract_content_length(headers)
      headers.each do |key, value|
        if key.downcase == 'content-length'
          return value.to_s == '0' ? '-' : value
        end
      end
      '-'
    end
  end
end
</pre>
<p>Como podemos ver, este é outro exemplo simples de um Middleware muito útil. No método call, é criado um registro simples do momento em que a aplicação principal é chamada, e um método de log pega todas as informações recebidas e formata em uma string que será impressa no servidor. Apesar de parecer difícil de entender a primeira vista, o método log apenas coleta e formata informações contidas no objeto env para adicionar ao log.</p>
<h2>Outros Middleware</h2>
<p>Existem outros ótimos exemplos de Middlewares pela rede. Optei por citar os mais simples aqui por questões didáticas. Dentre os que eu poderia citar como fundamentais, estão o <a href="http://github.com/rtomayko/rack-cache">rack-cache</a> do Ryan Tomayko, que é utilizado largamente em aplicações desenvolvidas com Rails. Posso citar também o &#8220;encolhedor&#8221; de javascript <a href="http://github.com/lucianopanaro/rack-javascript-minifier">Javascript Minifier</a>, o criador de <em>responses</em> JSON &#8220;Rack::JSONP&#8221; também é um bom exemplo, bem como &#8220;Rack::MailExceptions&#8221; e outros contidos no projeto rack-contrib.</p>
<p>Até o próximo post!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/rack/2009/10/superguia-rack-parte-3-middlewares/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Superguia Rack &#8211; Parte 2 &#8211; Dissecando o Rack</title>
		<link>http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-2-dissecando-o-rack/</link>
		<comments>http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-2-dissecando-o-rack/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 21:01:45 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[Rack]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=266</guid>
		<description><![CDATA[Continuando nossa saga iniciada no post anterior, voltaremos ao exemplo do HelloWorld para entendermos mais profundamente a estrutura de um objeto Rack. Como mencionado anteriormente, um este objeto deve possuir (na verdade responder a) um método call(env), retornando em sua resposta um array com 3 elementos. Veremos mais profundamente cada um desses elementos. class HelloWorld [...]]]></description>
			<content:encoded><![CDATA[<p>Continuando nossa saga iniciada <a href="http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-1/">no post anterior</a>, voltaremos ao exemplo do HelloWorld para entendermos mais profundamente a estrutura de um objeto Rack. Como mencionado anteriormente, um este objeto deve possuir (na verdade responder a) um método call(env), retornando em sua resposta um array com 3 elementos. Veremos mais profundamente cada um desses elementos.</p>
<pre class="brush: ruby">
class HelloWorld
  def call(env)
    [200, {"Content-Type" => "text/html"}, "Hello World"]
  end
end
</pre>
<h2>O método def call(env)</h2>
<h3>Env</h3>
<p>O parâmetro recebido pelo método call é uma hash com as propriedades do ambiente do visitante da aplicação. Se alterarmos o nosso HelloWorld para imprimir o objeto <em>env</em> ao invés da string, teremos algo parecido com isso:</p>
<pre>
{
"REQUEST_METHOD"=>"GET",
"REQUEST_PATH"=>"/",
"REQUEST_URI"=>"/",
"HTTP_VERSION"=>"HTTP/1.1",
"HTTP_HOST"=>"localhost:9292",
"HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; en-us) AppleWebKit/530.18 (KHTML, like Gecko) Version/4.0.1 Safari/530.18",
"HTTP_ACCEPT"=>"application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", "HTTP_ACCEPT_LANGUAGE"=>"en-us", "HTTP_ACCEPT_ENCODING"=>"gzip,deflate",
"HTTP_CONNECTION"=>"keep-alive", "GATEWAY_INTERFACE"=>"CGI/1.2",
"SERVER_NAME"=>"localhost",
"SERVER_PORT"=>"9292",
"SERVER_PROTOCOL"=>"HTTP/1.1",
"SERVER_SOFTWARE"=>"Mongrel 1.1.5",
 "PATH_INFO"=>"/",
 "SCRIPT_NAME"=>"",
 "REMOTE_ADDR"=>"127.0.0.1", "rack.version"=>[0, 1], "rack.input"=>#, "rack.errors"=>#>, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "rack.url_scheme"=>"http",
 "QUERY_STRING"=>""}
 </pre>
<p>Dentre as informações impressas, algumas são bem importantes, como:</p>
<ul>
<li><strong>REQUEST_METHOD</strong>: Informa qual o <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">verbo HTTP</a>  (GET, PUT, DELETE&#8230;) usado pelo usuário ao acessar a página.</li>
<li><strong>HTTP_USER_AGENT</strong>: Informa o browser do usuário, facilitando o tratamento para browsers diferente em sua aplicação.</li>
<li><strong>QUERY_STRING</strong>: Informa os argumentos passados após o &#8220;?&#8221; da url, útil para fazer parsing dos parâmetros.</li>
</ul>
<h3>Status</h3>
<p>O primeiro objeto retornado no array de resposta é um inteiro, representando o status da resposta que sua aplicação retornará no método. O 200 do nosso exemplo, representa &#8220;OK&#8221; segundo a <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">especificação do HTTP</a>. É aqui seu controle de exceção jogará aquele lindo &#8220;Erro 404&#8243; quando o usuário digitar incorretamente um sub-caminho de sua aplicação. ;-)</p>
<h3>HTTP Headers</h3>
<p>Cabeçalhos HTTP informam o tipo de retorno do pacote. O segundo objeto do nosso retorno deve OBRIGATORIAMENTE responder a um método &#8220;each&#8221; e devolver chaves e valores de seus elementos, tipicamente um Hash, como no nosso exemplo. A chave Content-Type, por exemplo, deve retornar o tipo de retorno a ser esperado, podendo ser HTML(&#8220;Content-Type&#8221; => &#8220;text/html&#8221;), XML, MP3 (&#8216;Content-Type&#8217; => &#8216;audio/mp3&#8242;), entre outros.</p>
<h3>Response Body</h3>
<p>O retorno &#8220;Body&#8221; deve responder ao método <em>each</em> retornando um array de strings. Este será o conteúdo que será apresentado ao usuário no navegador.</p>
<p><strong>ATENÇÃO</strong>: Segundo a documentação atual do Rack, o Body não deve mais ser uma simples string(como nos exemplos do post anterior). Aparentemente isto quebrará no Ruby 1.9.</p>
<h2>Rack:Builder</h2>
<p>É uma ferramenta que nos permite construir aplicações Rack utilizando uma DSL para &#8220;costurar&#8221; diferentes middlewares e aplicações. Os Builders são os parafusos das estantes, ou a cola que une as estruturas separadas criando uma inteiramente nova. Na verdade, o Builder é o cara que torna o a idéia do Rack tão genial. A facilidade que ele proporciona na criação de Middlewares ficará bem claro no próximo post.</p>
<p>Os métodos fornecidos pela DSL do Buider são:</p>
<p><span id="more-266"></span></p>
<ul>
<li>run</li>
<li>use</li>
<li>map</li>
</ul>
<h3>Rack::Builder#run</h3>
<p>É o método que o servidor web procurará para a execução da aplicação Rack. No exemplo abaixo, nosso builder é informado para rodar o bloco chamado clock a cada resquisição à porta 9292. Nada demais, por enquanto. Mas na medida que a aplicação for crescendo, é possível criar estruturas extremamente complexas que veremos posteriormente.</p>
<pre class="brush: ruby">
clock = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.now}"]]}
builder = Rack::Builder.new do
  run clock
end
Rack::Handler::Mongrel.run builder, :Port => 9292
</pre>
<h3>Rack::Builder#use</h3>
<p>É o método utilizado para acomplar novas middlewares à sua aplicação. No exemplo abaixo, o middleware <a href="http://rack.rubyforge.org/doc/Rack/CommonLogger.html">CommonLogger</a> é adicionado à nossa aplicação com apenas uma linha de código:</p>
<pre class="brush: ruby">
clock = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.now}"]]}
builder = Rack::Builder.new do
  use Rack::CommonLogger
  run clock
end
Rack::Handler::Mongrel.run builder, :Port => 9292
</pre>
<p>CommonLogger é um Middleware que adiciona a funcionalidade de log ao seu servidor. Rodando este exemplo, você terá um log semelhante ao de Rails e Sinatra em seu console, como no exemplo abaixo:</p>
<p>127.0.0.1 &#8211; - [25/Sep/2009 17:17:03] &#8220;GET / HTTP/1.1&#8243; 200 30 0.0002<br />
127.0.0.1 &#8211; - [25/Sep/2009 17:17:14] &#8220;GET / HTTP/1.1&#8243; 200 30 0.0002<br />
127.0.0.1 &#8211; - [25/Sep/2009 17:17:15] &#8220;GET /2 HTTP/1.1&#8243; 200 30 0.0002<br />
127.0.0.1 &#8211; - [25/Sep/2009 17:17:28] &#8220;GET /testand_log HTTP/1.1&#8243; 200 30 0.0002</p>
<h3>Rack::Builder#map</h3>
<p>Método utilizado para mapear (jura?) suas rotas HTTP. Não a toa, é semelhante ao routes.rb do Rails, afinal, ambos são implementações diretas das <em>best practices</em> de desenvolvimento web atual.</p>
<p>Para ilustrar, criaremos um exemplo de aplicação que além de informar as horas, oferece um caminho para que o usuário seja informado em que ano ele se encontra. </p>
<pre class="brush: ruby">
clock = Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.now}"]]}
builder = Rack::Builder.new do
  use Rack::CommonLogger
  map '/' do
    run clock
  end

  map '/year' do
    run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.new.year}"]] }
  end
end
Rack::Handler::Mongrel.run builder, :Port => 9292
</pre>
<p>Com este exemplo, se após iniciarmos a nossa aplicação tentarmos acessar a url http://localhost:9292/year, receberemos o ano atual em nosso browser.</p>
<p>Ok, mas e rotas aninhadas? Extremamente simples também! Acompanhem o exemplo abaixo.</p>
<pre class="brush: ruby">
builder = Rack::Builder.new do
  use Rack::CommonLogger
  map '/' do
    run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Welcome to my page"]]}
  end

  map '/clock' do
    map '/' do
      run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.now}"]] }
    end

    map '/year' do
      run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.now.year}"]] }
    end

    map '/hour' do
      run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{Time.now.hour}"]] }
    end    

  end
end
Rack::Handler::Mongrel.run builder, :Port => 9292
</pre>
<p>Ok, mas nós podemos seguir o conceito de DRY para evitar código desnecessário:</p>
<pre class="brush: ruby">
def create_proc(body_return)
  Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["#{body_return}"]]}
end

builder = Rack::Builder.new do
  use Rack::CommonLogger
  map '/' do
    run create_proc('Welcome to my page')
  end

  map '/clock' do
    map '/' do
      run create_proc(Time.now)
    end

    map '/year' do
      run create_proc(Time.now.year)
    end

    map '/hour' do
      run create_proc(Time.now.hour)
    end    

  end
end
Rack::Handler::Mongrel.run builder, :Port => 9292
</pre>
<p>Desta maneira, criamos uma aplicação com as seguintes rotas disponíveis:</p>
<ul>
<li>http://localhost:9292/</li>
<li>http://localhost:9292/clock</li>
<li>http://localhost:9292/clock/year</li>
<li>http://localhost:9292//clock/hour</li>
</ul>
<h2>Cenas do Próximo Capítulo</h2>
<p>Após aprendermos o <a href="http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-1/">conceito do Rack</a>, sua estrutura e os 3 principais métodos oferecidos para criação de aplicações, nos focaremos na criação de Middlewares no próximo post. Entenderemos seus conceitos e investigaremos alguns exemplos bem sucedidos disponíveis na web. Fiquem ligados!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-2-dissecando-o-rack/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Superguia Rack &#8211; Parte 1</title>
		<link>http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-1/</link>
		<comments>http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-1/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 03:30:28 +0000</pubDate>
		<dc:creator>bueno</dc:creator>
				<category><![CDATA[Rack]]></category>

		<guid isPermaLink="false">http://www.tbueno.com/blog/?p=253</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p><em>Este é o primeiro de uma série de posts dedicado ao <a href="http://rack.rubyforge.org/">Rack</a>. 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.</em></p>
<p><center><img alt="" src="http://rack.rubyforge.org/rack-logo.png" class="alignnone" width="400" height="200" /></center></p>
<h2>Introdução da Introdução</h2>
<p>Em fevereiro de 2007, Christian Neukirchen  postou em seu blog um artigo chamado <a href="http://chneukirchen.org/blog/archive/2007/02/introducing-rack.html">&#8220;Introduzindo Rack&#8221;</a> 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.</p>
<p>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.</p>
<p>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.</p>
<h2>O que é Rack?</h2>
<p>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 &#8220;<a href="http://www.slideshare.net/danwrong/8-minutes-on-rack-presentation">8 minutes on Rack</a>&#8220;:</p>
<blockquote><p>&#8220;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" =&gt; "text/html"}, "Hello World!"] ), então ele pode ser conectado a qualquer web server que suporte Rack&#8221;</p></blockquote>
<p>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.<br />
<span id="more-253"></span><br />
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.</p>
<p><center><img class="alignnone" title="Rack módulos empilhados" src="http://img3.imageshack.us/img3/3743/rackp.jpg" alt="" width="351" height="269" /></center></p>
<h2>Por que usar Rack?</h2>
<h3>Oferece controle de requisições, sessões e cookies automaticamente.</h3>
<p>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 <a href="http://github.com/rack/rack-contrib">rack-contrib</a>, uma coleção de Midlewares e ferramentas disponível para que qualquer um utilize em sua aplicação.</p>
<h3>Desenvolva middlewares que funcionam com Rails, Sinatra, Ramaze&#8230;</h3>
<p>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.</p>
<p>A lista de servidores que já suportam Rack é grande. Até agora, os seguintes já suportam:</p>
<ul>
<li>Mongrel</li>
<li>EventedMongrel</li>
<li>SwiftipliedMongrel</li>
<li>WEBrick</li>
<li>FCGI</li>
<li>CGI</li>
<li>SCGI</li>
<li>LiteSpeed</li>
<li>Thin</li>
<li>Ebb</li>
<li>Fuzed</li>
<li>Phusion Passenger</li>
<li>Unicorn</li>
</ul>
<p>Além dos servidores, praticamente todos os frameworks web desenvolvidos em Ruby já possuem adaptadores para Rack. A lista atual inclui os seguintes frameworks:</p>
<ul>
<li>Camping</li>
<li>Coset</li>
<li>Halcyon</li>
<li>Mack</li>
<li>Maveric</li>
<li>Merb</li>
<li>Racktools::SimpleApplication</li>
<li>Ramaze</li>
<li>Ruby on Rails</li>
<li>Rum</li>
<li>Sinatra</li>
<li>Sin</li>
<li>Vintage</li>
<li>Waves</li>
<li>Wee</li>
</ul>
<h2>Um exemplo minúsculo</h2>
<p>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:</p>
<pre class="brush: ruby">
    run Proc.new {|env| [200, {"Content-Type" => "text/html"}, "Hello Horld!"]}
</pre>
<p>Agora rode o arquivo via linha de comando usando rackup:</p>
<blockquote><p>
> rackup hello.ru</p></blockquote>
<p>E acesse o seguinte endereço em seu browser: http://localhost:8765/.</p>
<p>Pronto, você acabou de criar a página web no com o menor número de caracteres possível!</p>
<h2>Um segundo exemplo um pouco maior</h2>
<pre class="brush: ruby">
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
</pre>
<p>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.</p>
<p>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!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tbueno.com/blog/rack/2009/09/superguia-rack-parte-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
