Subsecciones

Introducción

Que es Rack

rack provides an minimal interface between webservers supporting Ruby and Ruby frameworks.

Ruby on Rails, Ramaze, Sinatra and other Ruby frameworks use it by default to talk to web servers, including Mongrel, Thin or Apache via Passenger.

Lo que hace Rack es que unifica la API de los diferentes web servers envolviendo las peticiones y respuestas HTTP en la forma mas simple posible.

  1. Rack includes handlers that connect Rack to all these web application servers (WEBrick, Mongrel etc.).

  2. Rack includes adapters that connect Rack to various web frameworks (Sinatra, Rails etc.).

  3. Between the server and the framework, Rack can be customized to your applications needs using middleware.

The fundamental idea behind Rack middleware is – come between the calling client and the server, process the HTTP request before sending it to the server, and processing the HTTP response before returning it to the client.

Que es una Aplicación Rack

Una aplicación Rack es un objeto que

  1. Debe responder al método call.
  2. El método call será llamado por el servidor y se le pasa como argumento env que es un hash que contiene información sobre el entorno CGI.
  3. El método call debe retornar un array con tres elementos:
    1. status: un entero
    2. headers: un hash
    3. body: un objeto que responde al método each y que para cada llamada de each retorna una String.

Un Ejemplo Sencillo

Rack uses a configuration file with extension .ru, that instructs Rack::Builder what middleware should it use and in which order. Let’s create one:

[~/sinatra/rackup/simple(master)]$ cat myapp.rb 
# my_app.rb
#
class MyApp
  def call env
    [200, {"Content-Type" => "text/html"}, ["Hello Rack Participants"]] 
  end
end

Esta es la aplicación Rack mas simple posible.

[~/sinatra/rackup/simple(master)]$ cat config.ru
require './myapp'
run MyApp.new
To start your newly created app, you need to use rackup command:

$ rackup config.ru
The application will be available by default on port 9292, so you have to visit http://localhost:9292 to see it.

Un Ejemplo con la Consola Interactiva de Ruby

Arranquemos la consola interactiva de Ruby. Cargamos rack:

1] pry(main)> require 'rack'
=> true
Comprobemos que handlers tenemos instalados:
[2] pry(main)> Rack::Handler::constants
=> [:CGI,
 :FastCGI,
 :Mongrel,
 :EventedMongrel,
 :SwiftipliedMongrel,
 :WEBrick,
 :LSWS,
 :SCGI,
 :Thin]

Todos los handlers Rack tienen un método run por lo que podemos llamar el método run en cualquiera de esos handlers instalados.

Un objeto que tiene un método call es cualquier objeto Proc y por tanto podemos usar una lambda que se atenga al protocolo de rack para nuestro ejemplo:

[3] pry(main)> Rack::Handler::WEBrick.run lambda 
                  { |env| [200, 
                           {"Content-Type" => "text/plain"}, 
                          ["Hello. The time is #{Time.now}"]] }
[2013-09-11 17:59:07] INFO  WEBrick 1.3.1
[2013-09-11 17:59:07] INFO  ruby 1.9.3 (2013-02-22) [x86_64-darwin11.4.2]
[2013-09-11 17:59:07] INFO  WEBrick::HTTPServer#start: pid=25123 port=8080
localhost - - [11/Sep/2013:17:59:26 WEST] "GET / HTTP/1.1" 200 44
- -> /
localhost - - [11/Sep/2013:17:59:26 WEST] "GET /favicon.ico HTTP/1.1" 200 44
- -> /favicon.ico
El primer argumento de run es nuestra aplicación Rack
lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
y el segundo es el conjunto de opciones para nuestro programa.

ahora podemos visitar la aplicación con nuestro navegador en http://localhost:8080

Casiano Rodríguez León
2015-01-25