Rack Environment

Actions offer a high level API built on top of Rack. If we need to access raw data from Rack environment we can use params.env.

Rack Middleware

Hanami mounts a very thin default middleware stack. Additional components can be mounted globally, at the application level, or locally.

Global Middleware

If we need a component that wraps all the applications (under apps/), we can edit config.ru at the root of the project.

  1. # config.ru
  2. require './config/environment'
  3. require 'rack/auth/basic'
  4. use Rack::Auth::Basic
  5. run Hanami.app

Project Middleware

There is also another way (the recommended one) to mount a Rack middleware: at the project level:

  1. # config/environment.rb
  2. Hanami.configure do
  3. # ...
  4. middleware.use Rack::Auth::Basic
  5. end

Application Middleware

If we need a component that’s only used by a specific application (under apps/), we can add it to the application’s configuration.

  1. # apps/web/application.rb
  2. require 'rack/auth/basic'
  3. module Web
  4. class Application < Hanami::Application
  5. configure do
  6. # ...
  7. middleware.use Rack::Auth::Basic
  8. end
  9. end
  10. end

Action Middleware

Sometimes we need a middleware only to be used for a set of well known resources. If we mount it at the global or application level the performance will start to degrade. Actions allow us to mount a fine grained middleware stack.

  1. # apps/web/controllers/sessions/create.rb
  2. require 'omniauth'
  3. module Web
  4. module Controllers
  5. module Sessions
  6. class Create
  7. include Web::Action
  8. use OmniAuth::Builder {
  9. # ...
  10. }
  11. def call(params)
  12. # ...
  13. end
  14. end
  15. end
  16. end
  17. end

We can use the following syntax to mount different middleware that require arguments.

  1. # apps/web/controllers/dashboard/index.rb
  2. module Web
  3. module Controllers
  4. module Dashboard
  5. class Index
  6. include Web::Action
  7. use XMiddleware.new('x', 123)
  8. use YMiddleware.new
  9. use ZMiddleware
  10. def call(params)
  11. # ...
  12. end
  13. end
  14. end
  15. end
  16. end