What kind of Rack?
According to Christian Neukirchen, the author of the rack rack, he was created to provide a minimal API for connecting web servers that support Ruby (WEBrick, Mongrel, etc.) and ruby ​​web frameworks (Rails, Sinatra, etc.).
Such frameworks, such as Sinatra, are built over Rack or they have a rack interface that allows web application servers to connect to them.
The purpose of rack is simple - it allows you to easily handle HTTP requests.
')
HTTP is a simple protocol: it basically describes the format of the data that is sent to the server and returned to the client. The HTTP request and HTTP response have a very similar structure. An HTTP request is a triplet consisting of a method-resource pair, a set of headers and a request body, while an HTTP HTTP response consists of a response code, a set of headers and an optional response body.
Mapping Rack is close to that. A Rack application is a ruby ​​object that has a call method that accepts a single argument, environment, and returns an array of three elements: status, headers, and the response body.
Rack includes handlers and adapters. The former connect it to ruby ​​web servers, the latter connect to frameworks.

Using middleware, you can change the rack to the needs of your application. The basic idea behind rack middleware is to process the request before it gets into the application, and to process the response before returning it to the client.
Documentation
rack.rubyforge.org/docInstall Rack
Please note that everything that is stated in this article has been tested on ruby ​​1.9.2 installed on Windows (
host - sir - approx. Lane ).
Check if you have a rack installed. To do this, open the console:
# irb --simple-prompt
>> require 'rack'
=> true
If require returns true, it means that the rack is installed. Otherwise, you will get an error like:
LoadError: no such file to load -- rack
This is fixed simply by the gem install rack command.
A quick excursion into the proc object
Remember the proc object? In hack, blocks are not objects, but they can be transformed into objects of the Proc class. This can be done by calling the Object class lambda method. A block created with lambda behaves like a ruby ​​method. And the Proc class has a call method that calls the block for execution.
>> my_rack_proc = lambda {puts 'Rack Intro'}
=> #<Proc:0x1fc9038@(irb):2(lambda)>
>> # method call invokes the block
?> my_rack_proc.call
Rack Intro
=> nil
The simplest rack app is my_rack_proc
As already mentioned, our rack application is an object (not a class) that responds to the call method and accepts one argument — an environment. The environment must be an instance of the Hash class. An application must return an array of three values: a status code (greater than or equal to 100), headers (also a hash), and bodies (the body is usually an array of strings, an application instance, or a file. The response body must respond to the each method and display only string values). Create our new proc object.
>> my_rack_proc = lambda { |env| [200, {}, ["Hello. The time is #{Time.now}"]] }
=> # <Proc:0x1f4c358@(irb):5(lambda)>
Now you can call my_rack_proc:
>> my_rack_proc.call({})
=> [200, {}, ["Hello. The time is 2011-10-24 09:18:56 +0530"]]
my_rack_proc - our one-line Rack.
In the example above, we used an empty hash for the headers. Instead, give something in the header as follows:
>> my_rack_proc = lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
=> #<Proc:0x1f4c358@(irb):5(lambda)>
>> my_rack_proc.call({})
=> [200, {"Content-Type" => "text/plain"}, ["Hello. The time is 2011-10-24 09:18:56 +0530"]]
We can run our rack application using any of the handlers.
Let's see what types of handlers are available to us:
>> Rack::Handler.constants
=> [:CGI, :FastCGI, :Mongrel, :EventedMongrel, :SwiftipliedMongrel, :WEBrick, :LSWS, :SCGI, :Thin]
To use WEBrick (by default WEBrick is a server installed with Ruby), enter:
>> Rack::Handler::WEBrick
=> Rack::Handler::WEBrick
All these handlers have a run method that runs the rack application:
>> Rack::Handler::WEBrick.run my_rack_proc
[2011-10-24 10:00:45] INFO WEBrick 1.3.1
[2011-10-24 10:00:45] INFO ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2011-10-24 10:00:45] INFO WEBrick::HTTPServer#start: pid=1788 port=80
Open the
localhost page in the browser and you should see a line like:
Hello. The time is 2011-10-24 10:02:20 +0530
Note: If you already have something running on port 80, you can run the application on another port.>> Rack::Handler::WEBrick.run my_rack_proc, :Port => 9876
[2011-10-24 11:32:21] INFO WEBrick 1.3.1
[2011-10-24 11:32:21] INFO ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2011-10-24 11:32:21] INFO WEBrick::HTTPServer # start: pid = 480 port = 9876
Another rack app is my_method
Rack-application is not necessarily lambda. It may also be a method.
>> def my_method env
>> [200, {}, ["method called"]]
>> end
=> nil
>> Rack::Handler::WEBrick.run method(:my_method)
[2011-10-24 14:32:05] INFO WEBrick 1.3.1
[2011-10-24 14:32:05] INFO ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2011-10-24 14:32:05] INFO WEBrick::HTTPServer#start: pid=1644 port=80
At
localhost you will again see:
method called
Method objects are created using
Object # method . They are associated with a specific object (and not just with a class). They can be used to call a method within an object.
Method.call is a method that calls the method (
Oh, cut, cut ... - approx. Lane ) with the specified arguments and returns the value that the method being called returns.
Using rackup
Heme rack comes with a pack of useful pieces, simplifying the life of the developer. One of these pieces is rackup.
Rackup is a useful tool for running rack-based applications. Rackup itself defines the environment in which it is running and runs your application as FastCGI, CGI, or autonomously with Mongrel or WEBrick — all with the same configuration.
To use rackup, you need to create its configuration file. By agreement, you must use the .ru extension of this config. By default, rackup starts on port 9292.
Let's create a config.ru file containing:
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
This file contains the word
run , which can be called by everyone that responds to the .call method.
To run the rack-application in the folder with the file config.ru enter:
$ rackup config.ru
[2011-10-24 15:18:03] INFO WEBrick 1.3.1
[2011-10-24 15:18:03] INFO ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2011-10-24 15:18:03] INFO WEBrick::HTTPServer # start: pid = 3304 port = 9292
Now at the address
localhost : 9292 / we will again be given the following page:
Hello. The time is 2011-10-24 15:18:10 +0530
Let's move our application from the config.ru file to my_app.rb:
Just change the config.ru:
require './my_app' run MyApp.new
Now you can run the application again (using “rackup config.ru”) and check if the page is being rendered to the browser.
Deploy the rack application to Heroku.
(This piece of the article was ruthlessly cut out by me, since it describes installing git on windows and deploying on heroku, which has nothing to do with the article itself. If you are interested, you can read it in the original - approx. Lane. )Using rack middleware
It was mentioned earlier that between the server and the rack framework can be customized for your needs using middleware.
Rackup also uses a method that accepts middleware. Let's use one of the middleware built into the rack.
You must have noticed that every time after changing the files of config.ru or my_app.rb it is necessary to restart the WEBrick server. This can be avoided using middleware Rack :: Reloader. Edit config.ru:
require './my_app' use Rack::Reloader run MyApp.new
And my_app.rb:
Launch the application and open the page with it in the browser. Now, change the text from “Hello Racks from the World to the World!” To “Hello Racks from the World!". After updating the page in the browser, you will see the edited text without restarting the web server.
Writing your own middleware
Middleware is always in practice used to wrap your internal application.
Let's create the simplest middleware that adds text to the http-response body. To do this, create a class MyRackMiddleware:
class MyRackMiddleware def initialize(appl) @appl = appl end def call(env) end end
In the code above, to get the original body of the response, we initialize the MyRackMiddleware class, passing it the application (appl).
Now let's change the .call method:
def call(env) status, headers, body = @appl.call(env)
In the above code, we have access to the original response body, which we can now change. Rack does not guarantee that the body will be a string. It can also be an object, but we know that when calling the .each method, everything returned will be a string. Use this in the .call method:
def call(env) status, headers, body = @appl.call(env) append_s = "... greetings from RubyLearning!!" [status, headers, body << append_s] end
Now we change the config.ru file:
require './my_app' require './myrackmiddleware' use Rack::Reloader use MyRackMiddleware run MyApp.new
We start the application and in the browser you can see “Hello Rack Participants from across the globe ... greetings from RubyLearning !!”
Rack and Sinatra
Finally, we give the simplest example of using rack along with the sinatra framework.
Create a trivial application my_sinatra.rb that will use rack middleware:
require 'sinatra' require './rackmiddleware' use RackMiddleware get '/' do 'Welcome to all' end
Let's now send a simple middleware class that will write to the console the time to process a request from an application. Create a file rackmiddleware.rb:
class RackMiddleware def initialize(appl) @appl = appl end def call(env) start = Time.now status, headers, body = @appl.call(env)
Now we will change the config.ru file:
require "./my_sinatra" run Sinatra::Application
(
Then again there is a block of text on how to deploy to Heroka, use git, etc. I don’t think it will be interesting to you - lane comment )
Now, after launching the application, a line with approximately the following content will be written to the console for each request:
?[36m2011-10-26T05:40:06+00:00 app[web.1]:?[0m *** Response Time ***: 0.000297385
That's all. Hope you enjoyed this rack entry. Happy Racking!