What is Ruby Rack? — Build your first Rack app

C.Dragon
5 min readSep 12, 2021

--

Rack provides a minimal interface between webservers that support Ruby and Ruby frameworks. Rack is a layer between the framework & the application server — RubyRack

Rack is a ruby web server interface that allows your application to communicates with the webserver. Thus, you can think of it as a translator for applications and web servers.

Rack interface

A simple Rack Application

Let’s create a straightforward rack application by running therackup command and get a feeling of using Rack:

$ gem install rack
$ mkdir rack_demo
$ cd rack_demo
$ rackup
configuration /Users/cdragon/Project/config.ru not found

Rackup is a useful tool provided by rack, which can launch applications that meet the Rack standard. By default, using rackup requires a configuration file usually ends with.ru.

$ touch config.ru

With a speedy setup:

# config.ruapp = Proc.new {
[
200,
{ "Content-Type" => "text/html" },
["Hello, Rack"]
]
}
run app

And….it’s up!

You can view your webpage at http://localhost:9292.

What does Rack do when running rackup?

The default specifications for Rack are:

  • Provide an object that can respond to the call method and receive a Hash type parameter (env)
  • Return an array containing the following three elements: status code(Integer), HTTP Headers(Hash), HTTP Body(Array)

In Ruby world, objects that can respond to the call method are Proc or Lumada. You can also create a class and define the call method by yourself, which will have the same result:

#config.ruclass App
def call(env)
[
200,
{"content-Type" => "text/html"},
["Hello, Rack #{env}"]
]
end
end
app = App.new
run app

The elements of the array accepted by Rack are actually the specifications of the HTTP message. As long as the App sends an HTTP message that meets the specifications of HTTP, it can be sent back to the UserAgent, and Rack acts as a bridge in the middle.

Why Rack? Can we talk directly to the Web server?

Imagine our Rails Application built to talk to WEBrick as its web server. What if one day we want to use Puma since it’s faster?

The bad thing is, your Rails is only able to speak with WEBricksince it was built so. Without having Rack as a bridge, it might take a month for the developer to get Rails to talk to Puma.

Having Rack as a translator between the web server and Ruby Apps gives us the flexibility to switch Web Server (Puma, WEBrick…) and Ruby Frameworks (Rails, Sinatra…)easily.

See more supported web servers and frameworks in Rack Document.

Bonus - Rack Middleware

During the execution of the rack between the server and framework, Rack allows us to customize your app needs using middleware.

The rack middleware is actually a class. When it is initialized, it will receive the entire Rack program calling the response method, which meets and return the specified rack specifications.

class App
def call(env)
[
200,
{"content-Type" => "text/html"},
["Hello, Rack"]
]
end
end
class MyMiddleware
def initialize(app, who = "no one")
@app = app
@who = who
end
def call(env)
status, headers, body = @app.call(env)
body << "<br />Powered by #{@who}!"
[status, headers, body]
end
end
app = App.new
use MyMiddleware, "It's me"
run app

The fun thing is, You can add as many middlewares as you like:

use MyMiddleware1
use MyMiddleware2
use MyMiddleware3
run App

Furthermore, Rack itself ships with tons of built-in middleware. For example, Rack::Attack is a middleware that is very useful for blocking and throttling abusive requests.

Connect the dots

Now we know Rails is one of the supported Rack frameworks. Try to run rackup it in your existing Rails project, and you’ll see your app up and running!

$ cd my_rails_app
$ rackup

No magic. You are able to find config.ru in your project’s directory. It was auto-generated when to initialize your Rails project.

Wrap up

Knowing Rack helps you understand how your application communicates with the webserver.

Hopefully, this post helps you understand more about behind the scene magic!

--

--

C.Dragon
C.Dragon

Written by C.Dragon

Author of Baby Dragon LineBot

Responses (1)