Read more

Rails: How to get the ordered list of used middlewares

Emanuel
August 17, 2020Software engineer at makandra GmbH

Rails middlewares are small code pieces that wrap requests to the application. The first middleware gets passed the request, invokes the next, and so on. Finally, the application is invoked, builds a response and passes it back to the last middleware. Each middleware now returns the response until the request is answered. Think of it like Russian Dolls, where each middleware is a doll and the application is the innermost item.

Illustration money motivation

Opscomplete powered by makandra brand

Save money by migrating from AWS to our fully managed hosting in Germany.

  • Trusted by over 100 customers
  • Ready to use with Ruby, Node.js, PHP
  • Proactive management by operations experts
Read more Show archive.org snapshot

You can run rake middleware to get the ordered list of used middlewares in a Rails application:

$> rake middleware

use Webpacker::DevServerProxy
use Rack::Sendfile
use ActionDispatch::Static
use Rack::LiveReload
use ActionDispatch::Executor
use ActiveSupport::Cache::Strategy::LocalCache::Middleware
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use ActionDispatch::RemoteIp
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use BetterErrors::Middleware
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ContentSecurityPolicy::Middleware
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use Rack::TempfileReaper
use Warden::Manager
use ExceptionNotification::Rack
use QueryDiet::Rack::ResetLogger
use OmniAuth::Strategies::SAML
run YourApp::Application.routes

This is helpful if you need to add or remove a middleware. Find more details in the docs for ActionDispatch::MiddlewareStack Show archive.org snapshot .

Since all middlewares run in each request, they must be very performant.

Example

Rails.application.configure do
  config.middleware.insert_after ActionDispatch::ContentSecurityPolicy::Middleware, Demo::Middleware
end
module Demo
  class Middleware

    # `@app` is the next (inner) middleware in the stack, Rack::Head in this example
    def initialize(app)
      @app = app
    end

    # This middleware will be called by ActionDispatch::ContentSecurityPolicy::Middleware
    def call(env)
      # env may be modified here (request pre-processing)

      # Here, the next middleware in the stack is invoked, passing in `env`.
      # `@app.call` will return what it receives from Rack::Head.
      status, headers, body = @app.call(env)

      # status, headers and body may be modified before returning (request post-processing)
      [status, headers, body]
    end
  end
end
Emanuel
August 17, 2020Software engineer at makandra GmbH
Posted by Emanuel to makandra dev (2020-08-17 13:40)