DEV Community

Rostislav Zhuravsky
Rostislav Zhuravsky

Posted on

How does rack preprocess your middlewares?

Tiny introduction

Have you ever thought about what happens when you start your rails server?
If no, I recommend you very much to learn more about Rack. If you prefer video resources, guys from thoughtbot have an amazing video especially for you.

So, but how do rack middlewares work underhood?

Just a simple example of config.ru with two middlewares:

# frozen_string_literal: true

class HelloWorld
  def call(env)
    [200, { 'Content-Type' => 'text/plain' }, ["Hello World\n"]]
  end
end

module Middleware
  class Base
    attr_reader :app

    def initialize(app)
      @app = app
    end

    def call(_env)
      raise NotImplementedError
    end
  end
end

class FirstMiddleware < Middleware::Base
  def call(env)
    status, headers, body = app.call(env)
    [status, headers, body << "First middleware body\n"]
  end
end

class SecondMiddleware < Middleware::Base
  def call(env)
    status, headers, body = app.call(env)
    [status, headers, body << "Second middleware body\n"]
  end
end

use FirstMiddleware
use SecondMiddleware
run HelloWorld.new

Let's start diving!

When rack processes config.ru it binds your code running with an instance of Rack::Builder.
Alt Text
Then each time when rack meets use AnyMiddlewareClass, builder prepares middleware class and puts into instance variable @use
Alt Text
Finally, the builder runs our application object but wraps it beforehand on all middlewares
Alt Text

Thanks a lot for your attention, useful links:

Top comments (0)