Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Rack Основы разработки на Ruby on Rails

Программа урока

  • HTTP
  • Rack
  • Middlewares

HTTP

HTTP Request

curl --head https://ru.hexlet.io
HTTP/2 200
server: nginx/1.21.1
date: Wed, 01 Dec 2021 12:50:51 GMT
content-type: text/html; charset=utf-8
vary: Accept-Encoding
vary: Accept
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-download-options: noopen
x-permitted-cross-domain-policies: none
referrer-policy: strict-origin-when-cross-origin
# ...
curl -X GET https://ru.hexlet.io
<!DOCTYPE html>
<html lang='ru' prefix='og: https://ogp.me/ns#'>
<head>
<title>Hexlet – больше чем школа программирования. Онлайн курсы, сообщество программистов</title>
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="" />
# ...

HTTP Response

  • Status (1xx, 2xx, 3xx, 4xx, 5xx)
  • Headers
  • Body

Rack

Rack это:

  • Стандарт интерфейса веб-сервера
  • Каркас для Middlewares
  • Gem

Стандарт интерфейса веб-сервера. Позволяет использовать различные сервера для запуска приложений

  • Rack::Handler::Puma
  • Rack::Handler::Thin
  • Rack::Handler::WEBrick

Приложение Rack

Приложение запускается командой ruby app.rb

# app.rb
require 'rack'

class MyApp
  def call(_env)
    [200, {'Content-Type' => 'text/html'}, ["Hello"]]
  end
end

Rack::Handler::Thin.run MyApp.run, :Port => 3000

Для Rack приложение требуется файл config.ru

# config.ru
class MyApp
  def call(_env)
    [200, {'Content-Type' => 'text/html'}, ["Hello"]]
  end
end

run MyApp.new

Запуск может выполняться одной из команд в зависимости от используемого сервера

# автоматически ищется файл config.ru
rackup
rackup -s thin
thin start
puma
unicorn
passenger start

Проверяем работу приложения

# Запустили сервер
rackup

# В другом терминале выполнили запрос
curl -X GET localhost:9292
# => Hello!

Middlewares

Назначение

  • Авторизация и аутентификация
  • Мониторинг
  • Логирование
  • Сериализация
  • Роутинг
  • Бизнес-логика

Rack: каркас для Middlewares

Приложение, содержащее миддлвар

# config.ru
class MyMiddleware
  def initialize(app1)
    @app1 = app1
  end

  def call(env)
    puts 'middleware_before'
    # env содержит запрос
    status, headers, body = @app1.call(env)
    puts 'middleware_after'
    request = Rack::Request.enw(env)
    if request.path == '/'
      case request.request_method
      when 'GET'
        [status, headers, body]
      when 'POST'
        [201, headers.merge({'x-created' => 'True'}), ['Item was successfully created']]
      end
    else
      [404, {}, ["Not Found"]]
    end
  end
end

class App
  def call(env)
    puts 'app_run'
    [200, {}, ["success"]]
  end
end

# Добавляется миддлвар
use MyMiddleware
# Запуск приложения
run App.new

Пример приложение, которые обрабатывает POST запрос


require 'json'

class MyMiddleware
  def initialize(app1)
    @app1 = app1
  end

  def call(env)
    status, headers, body = @app1.call(env)
    request = Rack::Request.new(env)

    body = {
      path: request.path,
      verb: request.request_method,
      ip: request.ip,
      cookies: request.cookies,
      params: request.params,
      body: JSON.parse(request.body.read)
    }

    [200, {}, [body.to_json]]
  end
end

class App
  def call(env)
  end
end

use MyMiddleware
run App.new

Запуск и выполнение запроса:

rackup
curl -x POST localhost:9292/users?sort=desc -d "{\"login\":\"admin\",\"password\":\"password\"}"

Приложение с базовой авторизацией

use Rack::Auth::Basic do |username, password|
  username == 'admin' && password == 'password'
end

class App
  def call(env)
    puts env["HTTP_AUTHORIZATION"]
    [200, {'Content-Type' => 'text/html'}, ["You are loggined successfully"]]
  end
end
run App.new

Запуск и запрос с авторизацией

rackup
curl -u admin:password -i http://localhost:9292

Тестирование

Запуск выполняется командой ruby test.rb

# test.rb
require 'minitest/autorun'
require 'rack/test'

class MyApp
  def call(env)
    [200, {'X-success' => true}, ["Success response"]]
  end
end

describe "MyApp" do
  include Rack::Test::Methods

  def app
    MyApp.new
  end

  it 'check response status' do
    get '/'
    assert last_response.ok?
  end

  it 'check response headers' do
    get '/'

    assert_equal last_response.headers, {'X-success' => true}
  end

  it 'check response body' do
    get '/'
    assert_equal last_response.body, "Success response"
  end
end

#
# https://www.rubydoc.info/github/brynary/rack-test/master/Rack/Test/Methods
# https://devhints.io/rack-test

Rack Gem

Rack Middlewares

  • Rack::Files
  • Rack::Events
  • Rack::Head
  • Rack::Lock
  • Rack::Reloader
  • Rack::Runtime
  • Rack::ShowException

Rack Helpers

  • Rack::Request
  • Rack::Response
  • Rack::MockRequest, Rack::MockResponse
  • Rack::MediaType
  • Rack::Mime
  • Rack::RewindableInput

Домашнее задание

Загрузите домашнее задание с помощью команды:

hexlet program download rails rack

Дополнительные материалы

  1. Курс Протокол HTTP
  2. Тестовые методы Rack

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Разработчик на Ruby on Rails
Профессия
Создает веб-приложения со скоростью света
1 июня 5 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Изображение Тото

Задавайте вопросы, если хотите обсудить теорию или упражнения. Команда поддержки Хекслета и опытные участники сообщества помогут найти ответы и решить задачу