Open-Source Wikis

/

Ruby on Rails

/

Features

/

Request lifecycle

rails/rails

Request lifecycle

How an incoming HTTP request becomes a response in Rails. This page traces the request through Rack, the middleware stack, the router, the controller, the view, and back.

End-to-end view

sequenceDiagram
    participant Browser
    participant Server as Web server (Puma)
    participant App as Rails::Application
    participant MW as Middleware stack
    participant Router as ActionDispatch::Routing::RouteSet
    participant Ctrl as Controller
    participant Model as ActiveRecord
    participant View as ActionView
    Browser->>Server: HTTP/1.1 GET /posts
    Server->>App: env hash (Rack)
    App->>MW: call(env)
    MW->>Router: env after middlewares
    Router->>Ctrl: ControllerClass.action(:index).call(env)
    Ctrl->>Model: Post.all
    Model-->>Ctrl: relation/records
    Ctrl->>View: render :index
    View-->>Ctrl: rendered HTML
    Ctrl-->>MW: [200, headers, body]
    MW-->>App: response
    App-->>Server: response
    Server-->>Browser: HTTP response

1. Rack and the application

The web server (Puma, Unicorn, Falcon) hands every request to Rails.application.call(env). Rails::Application is itself a Rack app — it inherits from Rails::Engine, which composes the middleware stack and the route set into a single Rack-compatible callable.

The entry point is Rails::Engine#call, defined in railties/lib/rails/engine.rb. It delegates to the built middleware stack at app.

2. Middleware stack

The default middleware stack is built by railties/lib/rails/application/default_middleware_stack.rb and lives in Rails.application.config.middleware. To inspect it in an app:

bin/rails middleware

Typical default order (top runs first):

  1. ActionDispatch::HostAuthorization — protect against DNS rebinding.
  2. Rack::SendfileX-Sendfile support.
  3. ActionDispatch::Static — serve files from public/ (only if config.public_file_server.enabled).
  4. ActionDispatch::Executor — wrap the request in Rails.application.executor.
  5. ActiveSupport::Cache::Strategy::LocalCache::Middleware — local cache scope.
  6. Rack::RuntimeX-Runtime header.
  7. Rack::MethodOverride_method parameter.
  8. ActionDispatch::RequestId — generate or read X-Request-Id.
  9. ActionDispatch::RemoteIp — set request.remote_ip through trusted proxies.
  10. Sprockets::Rails::QuietAssets — silence asset logs.
  11. Rails::Rack::Logger — request logging.
  12. ActionDispatch::ShowExceptions — convert exceptions to error pages.
  13. ActionDispatch::DebugExceptions — interactive web console / verbose errors in dev.
  14. ActionDispatch::ActionableExceptions — buttons in error pages to apply suggested fixes.
  15. ActionDispatch::Reloader — wrap with ActiveSupport::Reloader in dev.
  16. ActionDispatch::Callbacksbefore / after request callbacks.
  17. ActiveRecord::Migration::CheckPending — error in dev if migrations are pending.
  18. ActionDispatch::Cookies — populate request.cookie_jar.
  19. ActionDispatch::Session::CookieStore — populate request.session.
  20. ActionDispatch::Flash — flash hash.
  21. ActionDispatch::ContentSecurityPolicy::Middleware — assemble CSP headers.
  22. ActionDispatch::PermissionsPolicy::Middleware — feature-policy headers.
  23. Rack::Head — convert HEAD to GET internally.
  24. Rack::ConditionalGetIf-Modified-Since / If-None-Match.
  25. Rack::ETag — auto ETag.
  26. Rack::TempfileReaper — clean up Tempfiles after the request.

After the stack, the request reaches Rails.application.routes — the route set.

3. Routing

config/routes.rb is evaluated against ActionDispatch::Routing::Mapper. The mapper builds a Journey::Routes collection inside the RouteSet:

  • actionpack/lib/action_dispatch/routing/route_set.rb
  • actionpack/lib/action_dispatch/routing/mapper.rb
  • actionpack/lib/action_dispatch/journey/

At request time, RouteSet#call matches the path and HTTP method against the journey AST and dispatches to a controller via ControllerClass.action(:name).call(env).

4. Controller dispatch

Action Controller wraps the action invocation in callbacks, parameters, rendering, and instrumentation:

graph TD
    A[Controller.action :index] --> B[new instance]
    B --> C[before_action filters]
    C --> D{action_method}
    D --> E[implicit render]
    E --> F[after_action filters]
    F --> G[ActiveSupport::Notifications.instrument 'process_action.action_controller']
    G --> H[respond as Rack triple]

The action method runs business logic, possibly:

  • Querying models (Post.where(...)).
  • Setting instance variables for the view.
  • Issuing redirects, sending files, rendering JSON.

Controllers compose features by mixing in modules from actionpack/lib/action_controller/metal/. See packages/action-pack.

5. Model layer

ActiveRecord::Base.connection returns a connection from the per-thread connection pool. Queries flow through ActiveRecord::Relation (activerecord/lib/active_record/relation.rb) and QueryMethods (activerecord/lib/active_record/relation/query_methods.rb), then through Arel into the connection adapter.

The query_cache middleware (registered earlier) caches identical SQL within a single request.

For model-side details see packages/active-record.

6. View rendering

When the action calls render (or implicitly renders the action template), Action View takes over:

graph LR
    A[render :index] --> B[LookupContext finds template]
    B --> C[Template handler compiles]
    C --> D[OutputBuffer collects]
    D --> E[Layouts wrap output]
    E --> F[String response body]
  • actionview/lib/action_view/lookup_context.rb — search paths, formats, locales, variants.
  • actionview/lib/action_view/template.rb — wraps a compiled method.
  • actionview/lib/action_view/template/handlers/ — ERB, Builder, Raw.
  • actionview/lib/action_view/renderer/template_renderer.rb — drives rendering.
  • actionview/lib/action_view/layouts.rb — layout resolution.

Helpers (actionview/lib/action_view/helpers/) are mixed into the view context. form_with consumes ActiveModel::Naming and ActiveModel::Errors to build forms and error displays.

For more, see packages/action-view.

7. Response back through the stack

The controller returns [status, headers, body]. The middleware stack runs in reverse on the way out:

  • Rack::ETag computes the ETag.
  • ActionDispatch::ContentSecurityPolicy::Middleware adds CSP headers.
  • ActionDispatch::Cookies writes any modified cookies into Set-Cookie.
  • Rails::Rack::Logger emits the log line.
  • ActionDispatch::Executor cleans up the per-request executor scope (releases connections, runs after_call hooks).

Finally Rack writes the response to the socket.

Instrumentation

Throughout the request, ActiveSupport::Notifications events fire:

  • start_processing.action_controller, process_action.action_controller
  • sql.active_record
  • cache_read.active_support, cache_write.active_support
  • render_template.action_view, render_partial.action_view, render_collection.action_view

Subscribers in each component's log_subscriber.rb translate them into the familiar Started GET "/posts" ... log line.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Request lifecycle – Ruby on Rails wiki | Factory