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.
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.
call
.
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.
call
debe retornar un array con tres elementos:
status
: un entero
headers
: un hash
body
: un objeto que responde al método each
y que para cada llamada de
each
retorna una String.
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.newTo start your newly created app, you need to use
rackup
command:
$ rackup config.ruThe application will be available by default on port 9292, so you have to visit
http://localhost:9292
to see it.
Donde se encuentra este ejemplo:
[~/sinatra/rack/rack-simple(env)]$ pwd -P /Users/casiano/local/src/ruby/sinatra/rack/rackup/simple
[~/sinatra/rack/rack-simple(env)]$ git remote -v origin git@github.com:crguezl/a-quick-introduction-to-rack.git (fetch) origin git@github.com:crguezl/a-quick-introduction-to-rack.git (push)
Arranquemos la consola interactiva de Ruby. Cargamos rack
:
1] pry(main)> require 'rack' => trueComprobemos 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.icoEl 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