Как устроен реквест цикл в рельсах
Цикл запроса в Ruby on Rails (request cycle) описывает весь путь HTTP-запроса от его получения сервером до возврата ответа пользователю. Этот процесс является ядром веб-приложения на Rails и включает множество уровней: веб-сервер, маршрутизацию, контроллеры, модели, виды и middleware. Ниже подробно разобраны все этапы запроса.
1. Веб-сервер получает запрос
Rails-приложение обычно работает за обратным прокси, например, Nginx или Apache. Внутри работает веб-сервер, поддерживающий Rack-интерфейс, например:
-
Puma (по умолчанию в Rails)
-
Unicorn
-
Passenger
Когда пользователь отправляет HTTP-запрос (например, GET /articles), этот запрос доходит до веб-сервера, который затем передаёт его приложению через Rack — интерфейс между веб-сервером и приложением Ruby.
2. Rack-интерфейс
Rack определяет API, через который веб-сервер взаимодействует с приложением. Он передаёт окружение (env — хэш с HTTP-данными) в Rails и ожидает в ответ массив из трёх элементов:
[status, headers, body]
Rails реализует этот интерфейс в классе Rails::Application, и все middleware проходят через этот слой.
3. Middleware (Rack middleware)
До того как запрос попадёт в маршрутизатор и контроллер, он проходит через цепочку middleware — компонентов, обрабатывающих запрос или ответ:
-
Rack::Sendfile — отвечает за отдачу статических файлов
-
Rack::Runtime — добавляет время выполнения
-
ActionDispatch::Cookies — обрабатывает cookies
-
ActionDispatch::Session::CookieStore — сессии
-
ActionDispatch::Flash — флеш-сообщения
-
Rack::MethodOverride — поддержка PUT/DELETE через POST-запрос
-
и др.
Middleware может изменять env, остановить обработку (возвращая response) или продолжить вызов следующего middleware.
4. Router (маршрутизатор)
После middleware запрос попадает в маршрутизатор — Rails.application.routes. Он сравнивает путь запроса и HTTP-метод с маршрутами, определёнными в config/routes.rb.
get '/articles', to: 'articles#index'
Если найдено совпадение, маршрут определяет:
-
контроллер (ArticlesController)
-
экшн (index)
-
параметры (params[:id] и др.)
5. Controller (контроллер)
Маршрут передаёт управление соответствующему контроллеру. Rails создаёт экземпляр контроллера и вызывает нужное действие (index, show, create, и т.д.).
Внутри контроллера:
-
Обрабатываются параметры запроса (params)
-
Выполняется бизнес-логика
-
При необходимости запрашиваются данные из модели
-
Возвращается ответ (HTML, JSON, редирект и т.д.)
Контроллер может использовать:
-
фильтры (before_action, after_action)
-
работу с куки и сессиями
-
хелперы, рендеринг, редиректы
6. Model (модель, ActiveRecord)
Если экшн требует взаимодействия с базой данных, вызываются методы модели. Rails использует ActiveRecord — реализацию паттерна ORM (Object-Relational Mapping):
@articles = Article.where(published: true)
Каждая модель — это Ruby-класс, связанный с таблицей в базе данных. Запросы преобразуются в SQL и выполняются через адаптер к СУБД (например, PostgreSQL, MySQL, SQLite).
Модель также может выполнять валидации, колбэки и ассоциации (has_many, belongs_to, и т.д.).
7. View (представление, шаблоны)
После завершения логики в контроллере вызывается рендеринг представления:
-
По умолчанию рендерится шаблон, соответствующий имени действия: views/articles/index.html.erb
-
Можно явно указать другой шаблон: render 'shared/header'
-
Можно вернуть JSON: render json: @articles
Rails использует шаблонизатор ERB (Embedded Ruby) или альтернативы (HAML, Slim) для вставки Ruby-кода в HTML.
View может также использовать layout (views/layouts/application.html.erb) и partials (_form.html.erb и т.д.).
8. Формирование ответа
После рендеринга ActionController формирует полноценный HTTP-ответ:
-
Статус-код (200, 404, 500 и т.д.)
-
Заголовки (Content-Type, Set-Cookie, и др.)
-
Тело ответа (HTML, JSON, XML)
Финальный ответ формируется в виде Rack-суммки: [status, headers, body].
9. Ответ проходит обратно через middleware
Перед тем как попасть к клиенту, ответ возвращается обратно через те же Rack middleware, но уже в обратном направлении. Это может быть полезно для:
-
логирования (Rack::Logger)
-
компрессии (Rack::Deflater)
-
модификации заголовков
-
записи cookies или сессий
10. Ответ отправляется браузеру
Rack возвращает ответ веб-серверу, который уже передаёт его клиенту (браузеру или другому HTTP-клиенту).
Браузер получает статус, заголовки и тело и отображает страницу или обрабатывает данные (например, в случае API).
Визуальная схема
HTTP-запрос
↓
Веб-сервер (Puma/Nginx)
↓
Rack (интерфейс)
↓
Middleware (цепочка Rack middleware)
↓
Router (routes.rb)
↓
Controller (логика)
↓
Model (база данных)
↓
View (рендеринг)
↓
Response
↓
Middleware (обратный проход)
↓
Rack → Веб-сервер
↓
HTTP-ответ клиенту
Rails Request Cycle — это архитектура, объединяющая множество компонентов в чётко определённую цепочку обработки HTTP-запроса. Это позволяет легко масштабировать, тестировать и расширять поведение веб-приложения.