Дружимся с Rack #1: Hello Rack!

октября 23, 2010  |  Published in Rack  |  2 Comments

rack

Сообщество 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. Это проявляется в том, что:

  1. Отвечает методу call, который принимает один единственный аргумент — environment.
  2. 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


Оригинал статьи:

Tags: ,

Responses

  1. says:

    марта 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

  2. admin says:

    мая 4, 2013 at 08:56 (#)

    Да, там должен быть массив. Спасибо.

Leave a Response

Для подсветки кода используйте BB - коды: [language]...[/language], где language может быть: ruby, javascript, css, html.