Это руководство раскрывает интеграцию Rails и Rack и взаимодействие с другими компонентами Rack.
После прочтения этого руководства, вы узнаете:
Это руководство предполагает практические знания протокола Rack и такие концепции Rack, как промежуточные программы (middlewares), карты (maps) url и Rack::Builder
.
Rack представляет собой минимальный, модульный и адаптивный интерфейс для разработки веб-приложений на Ruby. Оборачивая запросы и отклики HTTP как можно более простым образом, он объединил и очистил API для веб-серверов, веб-фреймворков и промежуточных программ (так называемых middleware) до единственного метода call.
Объяснение того, как работает Rack, на самом деле не является темой этого руководства. Если вы не знакомы с основами Rack, обратитесь к разделу Источники.
Rails.application
это основной объект приложения Rack в приложении Rails. Любой совместимый с Rack веб-сервер должен использовать объект Rails.application
для обслуживания приложения Rails. Rails.application
ссылается на тот же объект приложения.
rails server
rails server
выполняет основную задачу по созданию объекта Rack::Server
и запуску веб-сервера.
Вот как rails server
создает экземпляр Rack::Server
Rails::Server.new.tap do |server| require APP_PATH Dir.chdir(Rails.application.root) server.start end
Rails::Server
унаследован от Rack::Server
и вызывает метод Rack::Server#start
следующим образом:
class Server < ::Rack::Server def start ... super end end
rackup
Для использования rackup
вместо рельсового rails server
, следует поместить следующее в config.ru
в корневой директории приложения Rails:
# Rails.root/config.ru require_relative 'config/environment' run Rails.application
И запустить сервер:
$ rackup config.ru
Чтобы узнать больше о различных опциях rackup
, вы можете выполнить:
$ rackup --help
Промежуточные программы загружаются один раз и не отслеживаются на предмет изменений. Необходимо перезагрузить сервер, чтобы отразить изменения в запущенном приложении.
Многие внутренние компоненты Action Dispatcher реализованы как промежуточные программы Rack. Rails::Application
использует ActionDispatch::MiddlewareStack
для объединения различных внутренних и внешних промежуточных программ для формирования полноценного приложения Rails Rack.
ActionDispatch::MiddlewareStack
это эквивалент Rack::Builder
в Rails, сделанный с большей гибкостью и приспособленностью к требованиям Rails.
В Rails имеется удобная задача для просмотра используемого стека промежуточных программ:
$ bin/rails middleware
Для свежесгенерированного приложения Rails он может выдать что-то наподобие:
use Rack::Sendfile use ActionDispatch::Static use ActionDispatch::Executor 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::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/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
Значительная часть функциональности Action Controller реализована как промежуточные программы. Следующий перечень объясняет назначение каждой из них:
Rack::Sendfile
config.action_dispatch.x_sendfile_header
.
ActionDispatch::Static
config.public_file_server.enabled
является false.
Rack::Lock
env["rack.multithread"]
в false
и оборачивает приложение в мьютекс.
ActionDispatch::Executor
ActiveSupport::Cache::Strategy::LocalCache::Middleware
Rack::Runtime
Rack::MethodOverride
params[:_method]
. Эта промежуточная программа поддерживает типы HTTP методов PUT и DELETE.
ActionDispatch::RequestId
X-Request-Id
и включает метод ActionDispatch::Request#request_id
.
ActionDispatch::RemoteIp
Sprockets::Rails::QuietAssets
Rails::Rack::Logger
ActionDispatch::ShowExceptions
ActionDispatch::DebugExceptions
ActionDispatch::Reloader
ActionDispatch::Callbacks
ActiveRecord::Migration::CheckPending
ActiveRecord::PendingMigrationError
, если какие-то миграции отложены.
ActionDispatch::Cookies
ActionDispatch::Session::CookieStore
ActionDispatch::Flash
config.action_controller.session_store
присвоено значение.
ActionDispatch::ContentSecurityPolicy::Middleware
Rack::Head
GET
и обслуживает их соответствующим образом.
Rack::ConditionalGet
GET
", чтобы сервер ничего не отвечал, если страница не изменилась.
Rack::ETag
Rack::TempfileReaper
Можете использовать любые из этих промежуточных программ в своем стеке Rack.