Дружимся с Rack #1: Hello Rack!
октября 23, 2010 | Published in Rack | 2 Comments
Сообщество Ruby обогащается новыми фреймворками почти каждую неделю, но среди них Rack не получил достаточного внимания которого он действительно заслуживает.
Rack изначально разрабатывался под вдохновением от пайтоновского wsgi и быстро стал фактически application/server — интерфейсом для всего сообщества Ruby — программистов благодаря своей простоте и перфекционизму создателей.
Что есть Rack?
Rack предоставляет минималичтичный, модульный и адаптируемый интерфейс для разработки веб приложений на языке программирования Ruby (ничего не понятно, правда?). Вместе с оберткой HTTP-запросов и ответами в простейший возможный способ, он красиво объединяет в себе API для взаимодействия с веб серверами, веб фреймворков и приложений написанных без использования фреймворков, а также программы, находящиеся между двух лагерей (так называемое middleware) в единый вызов метода.
- Документация Rack API
Спецификация Rack
Спецификация Rack определяет как в действительности Rack application и веб сервер должны взаимоодействовать между собой:
Rack application является объектом (не классом) Ruby, который отвечает на вызов. Вызов получает только один аргумент, environment и возвращает массив состоящий из 3х значений: status, headers и body.
- Из спецификации Rack
Эта спецификация не совсем коректна. Вы можете найти ее .
Грубо говоря, вы не нуждаетесь в gem’е Rack при написании Rack — приложений. Просто придерживайтесь правил установленных в спецификации и все будет ок!
Gem Rack
Gem Rack — это коллекция утилит и вспомогательных классов для того, чтобы сделать жизнь более простой для всех разработчиков rack — приложений. Он включает базовые реализации запросов, ответов, куков и сессий. Кроме того добротный набор полезнных rack middleware. Короче, устанавливайте gem rack, он вам понадобится!
$ sudo gem install rack
Повыводничаем!
- Rack — фреймворк для создания своего собственного фреймворка.
- Rack предоставляет интерфейс взаимодействия различных веб серверов и вашего фреймворка / приложения. Делая взаимодействие вашего приложения с различными веб серверами, поддерживаемыми rack (Phusion Passenger, LiteSpeed, Mongrel, Thin, Ebb, Webrick — вот названия некоторых), очень простым.
- Rack позволяет вам сразу браться за дело благодаря абстрагированию от сервера. Вы свободно получаете запрос, ответ, куки, парметры и сессии без специальной адаптации приложения к какому-либо серверу.
- Делает вышеописанное возможным для использования во множестве фреймворков и приложений, без возникновения каких-либо проблем и butthurt. Интеграция Rack в Ruby on Rails и Sinatra — хорошее тому подтверждение.
- Middleware! Думайте о middleware как о before_filter и after_filter в Ruby on Rails, которые многократно используются в различных работающих на основе Rack фреймворках и приложениях. Например вы можете использовать Anti-spamming middleware в Rack для вашего Ruby on Rails — приложения, приложения написанного на Sinatra, а также приложения, написаного без использования какого-либо фреймворка!
Чтобы не быть голословным: Примеры
Давайте начнем с простейшего примера rack — приложения, использующего сервер WEBrick (в оригинале Mongrel, но у меня с ним возникли проблемы).
require 'rubygems' require 'rack' class HelloWorld def call(env) [200, {"Content-Type" => "text/html"}, ["Hello Rack!"]] end end Rack::Handler::WEBrick.run HelloWorld.new, :Port => 9292
Код выше передает экземпляр класса HelloWorld в WEBrick’овый rack handler и запускает сервер WEBrick на 9292 порту.
Объект HelloWorld соответствует спецификации rack. Это проявляется в том, что:
- Отвечает методу call, который принимает один единственный аргумент — environment.
- Call возвращает массив [http_atatus_code, response_headers_hash, body]
И это все! Если вы запустите этот скрипт и перейдете по адресу http://localhost:9292, то вы увидите текст «Hello Rack!»
Но стойте! Proc также отвечает вызову! Так почему бы не использовать процедуру (proc)? Какие проблемы?! Используем:
require 'rubygems' require 'rack' Rack::Handler::Mongrel.run proc {|env| [200, {"Content-Type" => "text/html"}, "Hello Rack!"]}, :Port => 9292
Еще один типичный способ заключается в использовании method(:method_name), который возвращает объект класса Method:
require 'rubygems' require 'rack' def application(env) [200, {"Content-Type" => "text/html"}, "Hello Rack!"] end Rack::Handler::Mongrel.run method(:application), :Port => 9292
Примите тот факт, что любая ваша реализация «Hello World» отсталая. Вы не сможете написать более быстрое приложение «Hello World» на Ruby, чем то, что в примере выше.
Rackup!
Как я говорил ранее, gem rack поставляется с целым букетом полезных middleware, которые делают жизнь разработчика легче. Rackup одна из этих самых штуковин. В предыдущем примере, я использовал WEBrick’овый handler Rack::Handler::WEBrick непосредственно, и даже длинный номер порта. С помощью rackup эти вещи становятся настраиваемыми! Однако, для использования rackup, вам следует предоставить ему файл конфигурации. Для примера выше, файл конфигурации будет выглядеть приблизительно так:
# config.ru run Proc.new {|env| [200, {"Content-Type" => "text/html"}, ["Hello Rack!"]]}
Всего лишь одна строка! Согласно соглашению вы должны использовать расширение .ru для файлов конфигурации rackup. Поддержка его запуском RackObject и вы готовы:
$ rackup config.ru
По умолчанию, rackup запускает сервер на 9292 порту. Однако, вы можете изменить это с помощью rackup опции -p. Пример:
$ rackup config.ru -p 8088
За большей информацией обращайтесь к RTFM:
$ rackup —help
Оригинал статьи:
марта 20, 2013 at 13:21 (#)
Первый листинг нужно исправить на это:
require ‘rubygems’
require ‘rack’
class HelloWorld
def call(env)
[200, {"Content-Type" => "text/html"}, ["Hello Rack!"]] #обрати внимание на hello rack
end
end
Rack::Handler::WEBrick.run HelloWorld.new, :Port => 9292
мая 4, 2013 at 08:56 (#)
Да, там должен быть массив. Спасибо.