Sobes.tech
Middle+

Jak działa cykl obsługi żądania w Ruby on Rails?

sobes.tech AI

Odpowiedź od AI

  1. Serwer internetowy (np. Puma, Unicorn): Przyjmuje nadchodzące żądanie HTTP.
  2. Rack: Interfejs między serwerem internetowym a aplikacją Rails. Serwer internetowy opakowuje żądanie w obiekt Rack (środowisko Rack), który jest przekazywany do aplikacji Rails.
  3. Aplikacja Rails: Wewnątrz interfejsu Rack, aplikacja Rails obsługuje żądanie. Główne etapy:
    • Stos Middleware: Zestaw programów pośrednich (middleware), które wykonują różne zadania przed i po obsłudze żądania (np. routing, parsowanie parametrów, buforowanie, zarządzanie sesjami).
    • Router: Określa, który kontroler i akcja mają obsłużyć żądanie na podstawie URL i metody HTTP.
    • Dyspozytor: Kieruje żądanie do znalezionego kontrolera i akcji.
    • Kontroler: Wykonuje logikę biznesową. Może współpracować z modelami (do pracy z danymi) i renderować widoki.
    • Widoki: Widoki (szablony) generują HTML, JSON lub inne formaty odpowiedzi. Mogą korzystać z silników szablonów (ERB, Haml, Slim).
    • Odpowiedź: Kontroler tworzy obiekt odpowiedzi, który zawiera status HTTP, nagłówki i ciało odpowiedzi.
  4. Powrót przez stos Middleware: Obiekt odpowiedzi przechodzi z powrotem przez stos middleware do końcowego przetwarzania.
  5. Rack: Przekształca obiekt odpowiedzi Rails do formatu zrozumiałego dla serwera internetowego.
  6. Serwer internetowy: Wysyła sformatowaną odpowiedź HTTP do klienta.
# Przybliżony przepływ w pseudokodzie Rails

module Rails
  class Application
    def call(env) # env - środowisko Rack
      # Stos Middleware (uproszczony)
      # Rails::Rack::Logger.new.call(env) -> ... -> Rails::Rack::Failsafe.new.call(env)

      # Routing
      request = ActionDispatch::Request.new(env)
      route = Rails.application.routes.recognize(request) # Znajduje odpowiednią trasę

      # Dyspozycja
      controller_class = route[:controller].classify.constantize # Pobiera klasę kontrolera
      controller_instance = controller_class.new

      # Wykonanie akcji
      response = controller_instance.process(route[:action], request) # Wywołuje akcję kontrolera

      # Powrót przez Middleware
      # ... (powrót przez middleware)

      response.to_a # Konwertuje odpowiedź do formatu Rack [status, nagłówki, ciało]
    end
  end
end