There and Rack Again

What is Rack and Why

🐦 @zerosumjames 💌 🌐


  1. Understand how HTTP requests get to your app.
  2. Understand the role that rack plays.
  3. Make your own rack application.

HTTP Requests

						GET /uses HTTP/1.1
GET The HTTP verb. Commonly GET, POST, PATCH or DELETE.
/uses The path being requested.
HTTP/1.1 The version of HTTP to be used.
Host: One of potentially several headers passed along with the request.

HTTP Responses

						HTTP/1.1 200 OK
						Date: Mon, 23 May 2005 22:38:34 GMT
						Content-Type: text/html; charset=UTF-8
						Content-Length: 155
						Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
						Server: Apache/ (Unix) (Red-Hat/Linux)
						Accept-Ranges: bytes
						Connection: close

						  <head><title>An Example Page</title></head>
						  <body><p>Hello World!</p></body>

The Path

How does the request reach our Ruby application?

_______________  |                   |
|             |  |     webserver     |
|  "the web"  |->|  (nginx, apache   |
|_____________|  |       etc.)       |
                 __________V__________  ______________________
                 |                   |  |                    |
                 |    app server     |  |                    |
                 |  (puma, unicorn   |->|  your application  |
                 |      etc.)        |  |                    |
                 |___________________|  |____________________|

The Littlest Server

						require 'socket'
						server = # Bind to a socket

						while session = server.accept # Take the next connection
						  request = session.gets # Read the request

						  session.print "HTTP/1.1 200\r\n" # Respond
						  session.print "Content-Type: text/html\r\n"
						  session.print "\r\n"
						  session.print "Hello world!"

						  session.close # Close the connection

Ruby Application Servers

What application servers are there?

unicorn, puma, passenger, thin, falcon, prax, okay, OKAY. That's enough. Jeez.

Your application server is going to want to pass requests to your application.

Do they speak the same language?

Who defines that language?


"a modular Ruby webserver interface"

Rack does the thinking, so you don't have to.

It's Everywhere

Your favourite Ruby (Rails, Hanami, Sinatra) applications are actually Rack applications.

What is a Rack application?

  • A Ruby object that responds to #call(env)
  • Accepts the Rack environment as the only argument.
  • Returns [status_code, headers, body].

Environment Goes In

						  "REQUEST_METHOD" => "GET",
						  "PATH_INFO" => "/uses",
						  "SERVER_PORT" => 80,
						  "REMOTE_ADDR" => "",
						  "HTTP_USER_AGENT" => "Mozilla/5.0 blah blah"
						  # lots more!

Response Comes Out

						  { 'Content-Type' => 'text/html' },
						  ["Hello, world!"]

Which application servers support Rack?


The Littlest Rack Application

            # app.rb
            class App
              def call(env)
                  { 'Content-Type' => 'text/html' },
                  ["Hello, world!"]

            require './app'


rackup is a useful tool for running Rack applications

						# Automatically looks for
						# and runs the application on port 3001
						rackup -p 3001

This is the configuration file used by Rack-based servers. Here's the one from a new Rails 6.1 project.

            require_relative "config/environment"
            run Rails.application


Add behaviour without changing your application.

Essentially also a rack application.

What's Middleware Good For?

  • Logging
  • Setting headers
  • Adding compression

Let's Make Rails

  • 78,913 commits
  • huge contributor community
  • corporate backing

Let's not.

Let's replicate a small subset of Rails-like features

Let's make...

  1. a router
  2. a controller
  3. a model
  4. a view
  5. some middleware

<insert incredible live coding sequence>


We just made a very (very) lightweight MVC framework.

No Rails, no Hanami, no Sinatra. Scarcely any gems at all.

Why is Rails so big if Rack is so smart?

What we've just done is Rack and a little Ruby code. Rails is Rack and a lot of Ruby code.


Ruby web frameworks do a heck of a lot, but we really owe a debt of gratitude to just plain ol' rack.


The top 100 Rack contributors as of 19th January 2021.

leahneukirchen, raggi, tenderlove, scytrin, josh, jeremyevans, ioquatix, rkh, spastorino, manveru, rtomayko, jeremy, deepj, josevalim, qerub, brainopia, oscardelben, rafaelfranca, postmodern, eileencodes, FooBarWidget, thomasklemm, yhirano55, zenspider, olleolleolle, changemewtf, krzysiek1507, jodosha, styd, kamipo, rinaldifonseca, lukaso, mtodd, tgxworld, sigmavirus24, vipulnsward, thedarkone, radar, jkowens, janko, matthewd, vais, schneems, sophiedeziel, thinkerbot, byroot, dkubb, fatkodima, SamSaffron, ender672, tonytonyjan, bestie, Drenmi, dblock, Jamie0, andrykonchin, alup, osamtimizer, lenny, felixbuenemann, evanphx, KitaitiMakoto, carlzulauf, technomancy, yeban, lanzhiheng, VBart, gjtorikian, alindeman, urielka, dayflower, eregon, davydovanton, martoche, candlerb, itnsk, esparta, AlexKVal, p8, NikolayRys, Sean0628, AlexWayfer, NickLaMuro, ChrisBr, igas, tomelm, tompng, CJKinni, ohler55, bdewater, da2x, okuramasafumi, kirs, prathamesh-sonpatki, greysteil, hyun-park, zzak, alecclarke, ziggythehamster, pvande, and many more