Rack — это минималистичный интерфейс между веб-серверами и Ruby-фреймворками, который стандартизирует взаимодействие между ними. Это основа многих популярных фреймворков, таких как Ruby on Rails, Sinatra и Hanami.
Основные концепции Rack
-
Интерфейс Rack:
- Rack определяет простой контракт (интерфейс), которому должны соответствовать и приложения, и серверы.
- Приложение Rack — это любой Ruby-объект, который отвечает на метод
call
и принимает env
(environment hash).
# Простейшее Rack-приложение
app = ->(env) { [200, {'Content-Type' => 'text/plain'}, ['Hello Rack!']] }
-
Структура ответа:
- Rack ожидает, что приложение вернет массив из трех элементов:
- HTTP статус (например, 200)
- Хэш заголовков
- Тело ответа (должно быть enumerable)
-
Middleware:
- Rack позволяет использовать цепочки middleware — компонентов, которые обрабатывают запрос и/или ответ.
- Каждый middleware оборачивает приложение, модифицируя входящий
env
или исходящий ответ.
# Пример middleware для логирования
class LoggerMiddleware
def initialize(app)
@app = app
end
def call(env)
puts "Request: #{env['REQUEST_METHOD']} #{env['PATH_INFO']}"
@app.call(env)
end
end
Почему Rack важен?
- Стандартизация: Позволяет любым совместимым веб-серверам (Puma, Unicorn, WEBrick) работать с любыми Rack-совместимыми фреймворками.
- Гибкость: Можно комбинировать middleware для добавления функциональности (аутентификация, кэширование и т.д.).
- Тестирование: Упрощает тестирование, так как приложения работают с простыми хэшами и массивами.
Пример конфигурации
# config.ru (стандартный файл конфигурации Rack)
require_relative 'my_app'
use Rack::Runtime
use Rack::Deflater
run MyApp.new
Резюмируем
Rack — это фундаментальный слой Ruby-веба, который:
- Определяет простой, но мощный интерфейс
- Позволяет совместимости между серверами и фреймворками
- Предоставляет механизм middleware для модульности
- Является основой для большинства Ruby-веб-технологий