Okay, but what is Rack?

Okay, but what is Rack?

"Rack", If you are Ruby on Rails Programmer you must have heard of this word. Doesn't matter if you know about it or not, this article may give you some new ideas and understanding.

Rack is

minimal interface between webservers that support Ruby and Ruby frameworks. You can think of as a brigde between webservers and rack compliant applications written in frameworks like 'Ruby on Rails or Sinatra or such'.

Let's take it step by step after a deep warm breath. We will look at the whole process of request response cycle in a web application written using Ruby on Rails framework.

  • Client requests some resource from a particular website. Say 'exampledomain.com/index.html'
  • The Internet Service Provider routes the request to particular system or set systems by the help of Domain Name System. 'System' here can be some computer/ virtual computer on cloud.
  • The Physical server(Our 'System') receives the request, it has some Operating system, system softwares for network communication and management, and a web server software to handle requests
  • This web server server may be Puma, Unicorn, WEBrick. Now it is task of this web server to get response from application server ( aka 'Our Web Application') and send it to our client.
  • The communication between web server and application server is done within set of rules called Rack protocol. There's the entry of word 'Rack'.

  • You might ask why there's need for protocol between web server and application server. So the answer would an analogy of two people from different countries who know english and hence can communicate with each other. Now we can replace the two people with any other two people who can speak English. English would be Rack in our analogy, web server and application server being the two people.

  • Hence, with Rack we can Easily switch web servers(Puma/Unicorn/WEBrick), Easily switch Ruby frameworks(Ruby on Rails/Sinatra) as long as both are Rack compliant, they will understand each other.

  • Another advantage is that we can can have any number of Rack Middleware between Rack and our application server. Rack Middleware is nothing but piece of ruby code which looks at the request before our application. 'Warden' is one such example of popular rack middleware. You can build you own middleware using Rack::Builder API.

  • Application Server is an object that responds to the call method, taking the environment hash as a parameter, and returning an Array with three elements: the HTTP response code, a Hash of headers, and the response body, which must respond to each. rack.github.io

  • Web server's 'run' method invokes this call method with request environment and our initial request of ''exampledomain.com/index.html'' reaches to corresponding controller via Rails Router. The controller returns the response and the response is sent to waiting web server thread in the Rack compliant form as shown below, which is then sent to client by the web server.

Sample response from Rack Compliant App, sent to Web server => [200, { content_type: "text/html"}, ["This is sample"]]

Finally, let us look a sample Rack App, It contains class App which is like our application server and Rack::Handler::Puma.run is our web server handler which will execute call method in App class for each request that comes to server. Again, this is a very small example of the whole setup explained above. But i hope you get the point.

require 'rack'
require 'rack/handler/puma'

class App
  def call(request)
   [200, { content_type: "application/json", body: "" }, [""]]
  end
end

Rack::Handler::Puma.run App.new

If you reached this far, there's a message for you in the image below

unicorn-magic.jpeg