Rails on Rack
Это руководство раскрывает интеграцию Rails и Rack и взаимодействие с другими компонентами Rack.
Это руководство раскрывает интеграцию Rails и Rack и взаимодействие с другими компонентами Rack.
После прочтения этого руководства, вы узнаете:
- Как использовать промежуточные программы Rack в своих приложениях Rails
- О стеке внутренних промежуточных программ Action Pack
- Как определять собственный стек промежуточных программ
Это руководство предполагает практические знания протокола Rack и такие концепции Rack, как промежуточные программы (middlewares), карты (maps) URL и Rack::Builder.
Введение в Rack
Rack представляет собой минимальный, модульный и адаптивный интерфейс для разработки веб-приложений на Ruby. Оборачивая запросы и отклики HTTP как можно более простым образом, он объединил и очистил API для веб-серверов, веб-фреймворков и промежуточных программ (так называемых middleware) до единственного метода call.
Объяснение того, как работает Rack, на самом деле не является темой этого руководства. Если вы не знакомы с основами Rack, обратитесь к разделу Источники.
Rails on Rack
Объект Rack приложения Rails
Rails.application это основной объект приложения Rack в приложении Rails. Любой совместимый с Rack веб-сервер должен использовать объект Rails.application для обслуживания приложения Rails. Rails.application ссылается на тот же объект приложения.
bin/rails server
bin/rails server выполняет основную задачу по созданию объекта Rack::Server и запуску веб-сервера.
Вот как bin/rails server создает экземпляр Rack::Server
Rails::Server.new.tap do |server|
require APP_PATH
Dir.chdir(Rails.application.root)
server.start
endRails::Server унаследован от Rack::Server и вызывает метод Rack::Server#start следующим образом:
class Server < ::Rack::Server
def start
# ...
super
end
endrackup
Для использования rackup вместо рельсового bin/rails server, следует поместить следующее в config.ru в корневой директории приложения Rails:
# Rails.root/config.ru
require_relative "config/environment"
run Rails.applicationИ запустить сервер:
$ rackup config.ruЧтобы узнать больше о различных опциях rackup, вы можете выполнить:
$ rackup --helpРазработка и автоматическая перезагрузка
Промежуточные программы загружаются один раз и не отслеживаются на предмет изменений. Необходимо перезагрузить сервер, чтобы отразить изменения в запущенном приложении.
Стек промежуточных программ Action Dispatcher
Многие внутренние компоненты Action Dispatcher реализованы как промежуточные программы Rack. Rails::Application использует ActionDispatch::MiddlewareStack для объединения различных внутренних и внешних промежуточных программ для формирования полноценного приложения Rails Rack.
ActionDispatch::MiddlewareStack это эквивалент Rack::Builder в Rails, сделанный с большей гибкостью и приспособленностью к требованиям Rails.
Просмотр стека промежуточных программ
В Rails имеется удобная команда для просмотра используемого стека промежуточных программ:
$ bin/rails middlewareДля свежесгенерированного приложения Rails он может выдать что-то наподобие:
use ActionDispatch::HostAuthorization
use Rack::Sendfile
use ActionDispatch::Static
use ActionDispatch::Executor
use ActionDispatch::ServerTiming
use ActiveSupport::Cache::Strategy::LocalCache::Middleware
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use ActionDispatch::RemoteIp
use Sprockets::Rails::QuietAssets
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use WebConsole::Middleware
use ActionDispatch::DebugExceptions
use ActionDispatch::ActionableExceptions
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
run MyApp::Application.routesПромежуточные программы по умолчанию, показанные здесь (и некоторые другие) описываются в разделе Внутренние промежуточные программы ниже.
Настройка стека промежуточных программ
Rails предоставляет простой конфигурационный интерфейс config.middleware для добавления, удаления и модифицирования промежуточных программ в стеке промежуточных программ, из application.rb или конфигурационного файла определенной среды environments/<environment>.rb.
Добавление промежуточной программы
Добавить новую промежуточную программу в стек промежуточных программ можно с помощью следующих методов:
-
config.middleware.use(new_middleware, args)- Добавляет новую промежуточную программу в конец стека. -
config.middleware.insert_before(existing_middleware, new_middleware, args)- Добавляет промежуточную программу до определенной существующей промежуточной программы в стеке. -
config.middleware.insert_after(existing_middleware, new_middleware, args)- Добавляет промежуточную программу после определенной существующей промежуточной программы в стеке.
# config/application.rb
# Добавить Rack::BounceFavicon в конец
config.middleware.use Rack::BounceFavicon
# Добавить Lifo::Cache после ActionDispatch::Executor.
# Передать аргумент { page_cache: false } в Lifo::Cache.
config.middleware.insert_after ActionDispatch::Executor, Lifo::Cache, page_cache: falseПеремена местами промежуточных программ
Поменять местами существующие промежуточные программы в стеке можно с помощью config.middleware.swap.
# config/application.rb
# Поменять местами ActionDispatch::ShowExceptions с Lifo::ShowExceptions
config.middleware.swap ActionDispatch::ShowExceptions, Lifo::ShowExceptionsПеремещение промежуточных программ
Можно переместить существующую промежуточную программу в стеке промежуточных программ с помощью config.middleware.move_before и config.middleware.move_after.
# config/application.rb
# Перемещаем ActionDispatch::ShowExceptions перед Lifo::ShowExceptions
config.middleware.move_before Lifo::ShowExceptions, ActionDispatch::ShowExceptions# config/application.rb
# Перемещаем ActionDispatch::ShowExceptions после Lifo::ShowExceptions
config.middleware.move_after Lifo::ShowExceptions, ActionDispatch::ShowExceptionsУдаление промежуточных программ
Добавьте следующие строчки в конфигурацию вашего приложения:
# config/application.rb
config.middleware.delete "Rack::Runtime"Теперь, при просмотре стека промежуточных программ, вы увидите, что Rack::Runtime больше не является его частью.
$ bin/rails middleware
(in /Users/lifo/Rails/blog)
use ActionDispatch::Static
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x00000001c304c8>
...
run Rails.application.routesЕсли хотите убрать промежуточные программы, относящиеся к сессии, сделайте следующее:
# config/application.rb
config.middleware.delete ActionDispatch::Cookies
config.middleware.delete ActionDispatch::Session::CookieStore
config.middleware.delete ActionDispatch::FlashЧтобы убрать промежуточные программы, относящиеся к браузеру,
# config/application.rb
config.middleware.delete Rack::MethodOverrideЕсли хотите, чтобы была вызвана ошибка, когда пытаетесь удалить несуществующий элемент, используйте delete!.
# config/application.rb
config.middleware.delete! ActionDispatch::ExecutorСтек внутренних промежуточных программ
Значительная часть функциональности Action Controller реализована как промежуточные программы. Следующий перечень объясняет назначение каждой из них:
ActionDispatch::HostAuthorization
- Защищает от атак переназначения DNS, явно разрешая хосты, с которых может быть послан запрос. Смотрите инструкции в руководстве по конфигурированию.
Rack::Sendfile
- Устанавливает заголовки X-Sendfile, специфичные для сервера. Настраивается с помощью опции
config.action_dispatch.x_sendfile_header.
ActionDispatch::Static
- Используется для раздачи статичных файлов из директории public. Отключена, если
config.public_file_server.enabledявляется false.
Rack::Lock
- Устанавливает флажок
env["rack.multithread"]вfalseи оборачивает приложение в мьютекс.
ActionDispatch::Executor
- Используется для перезагрузки тредобезопасного кода при разработке.
ActionDispatch::ServerTiming
- Устанавливает заголовок
Server-Timing, содержащий метрики быстродействия для запроса.
ActiveSupport::Cache::Strategy::LocalCache::Middleware
- Используется для кэширования в памяти. Этот кэш не является тредобезопасным(thread safe).
Rack::Runtime
- Устанавливает заголовок X-Runtime, содержащий время (в секундах), затраченное на выполнение запроса.
Rack::MethodOverride
- Переопределяет метод, если установлен
params[:_method]. Эта промежуточная программа поддерживает типы HTTP методов PUT и DELETE.
ActionDispatch::RequestId
- Создает для отклика уникальный заголовок
X-Request-Idи включает методActionDispatch::Request#request_id.
ActionDispatch::RemoteIp
- Проверяет на IP-спуфинг атаки.
Sprockets::Rails::QuietAssets
- Подавляет вывод логгера для запросов ассета.
Rails::Rack::Logger
- Уведомляет логи, что начался запрос. После выполнения запроса, глушит все логи.
ActionDispatch::ShowExceptions
- Ловит все исключения, возвращаемые приложением и вызывает приложение для показа исключений, которое форматирует его для конечного пользователя.
ActionDispatch::DebugExceptions
- Ответственна за логирование исключений и показа отладочной страницы, если запрос локальный.
ActionDispatch::ActionableExceptions
- Предоставляет способ направления экшнов от страниц об ошибке Rails.
ActionDispatch::Reloader
- Предоставляет колбэки prepare и cleanup, предназначенные для перезагрузки кода во время разработки.
ActionDispatch::Callbacks
- Предоставляет колбэки для выполнения до и после направления запроса.
ActiveRecord::Migration::CheckPending
- Проверяет отложенные миграции и вызывает
ActiveRecord::PendingMigrationError, если какие-то миграции отложены.
ActionDispatch::Cookies
- Устанавливает для запроса куки.
ActionDispatch::Session::CookieStore
- Ответственна за хранение сессии в куки.
ActionDispatch::Flash
- Настраивает ключи flash. Доступно, только если
config.session_storeприсвоено значение.
ActionDispatch::ContentSecurityPolicy::Middleware
- Предоставляет DSL для настройки заголовка Content-Security-Policy.
Rack::Head
- Преобразует запросы HEAD в запросы
GETи обслуживает их соответствующим образом.
Rack::ConditionalGet
- Добавляет поддержку для "Conditional
GET", чтобы сервер ничего не отвечал, если страница не изменилась.
Rack::ETag
- Добавляет заголовок ETag во все строковые тела. ETags используются для проверки кэша.
Rack::TempfileReaper
- Очищает временные файлы, используемые для буферизации multipart запросов.
Можете использовать любые из этих промежуточных программ в своем стеке Rack.
Источники
Обучение Rack
Понимание промежуточных программ
Основы создания плагинов Rails
Плагин Rails - это либо расширение, либо модификация основного фреймворка. Плагины представляют:
Создание и настройка генераторов и шаблонов Rails
Генераторы Rails - необходимый инструмент, для улучшения своего рабочего процесса. С помощью этого руководства вы изучите, как создавать генераторы и настраивать существующие.