- понимать, как работают веб-приложения
- писать простые веб-приложение с бэкендом
Http-запросы от А до Я
Http-протокол
Что такое веб-сервер и как он работает
Работа с сетью (RubyRush)
HTTP Request Methods
-
Структура HTTP-запроса
-
Основные методы HTTP (get, post, put, patch, delete)
-
Http-заголовки
-
Статусы ответов
-
что происходит, когда мы набираем адрес сайта в адресной строке (и сабмитим)
-
чем отличается бэкенд от фронтенда
-
что такое api?
Посмотрим информацию об http-запросе в браузере:
- F12 или правая кнопка мыши + inspect => откроются developer tools
- Выберите вкладку network и обновите страницу
- Выберите какой-нибудь HTTP request и изучите информацию о нём справа
Обратите внимание на заголовки запроса, заголовки ответа, вкладку с телом ответа.
Посмотрим информацию о запросе, к-й сделаем через curl.
curl - command line tool and library for transferring data with URLs
Установка:
sudo apt-get install curl
Запрос
curl github.com
Подробнее (verbose):
curl -v ваш_урл
Подробнее + follow redirects:
curl -Lv ваш_урл
Запрос c method "head":
curl -Lv --head https://google.com
Наша программа на руби тоже может работать в кач-ве клиента.
Пример с помощью стандартной библиотеки net/http
require 'uri'
require 'net/http'
require 'json'
uri = URI('https://api.thecatapi.com/v1/images/search?size=med&mime_types=jpg&format=json&has_breeds=true&order=RANDOM&page=0&limit=1')
res = Net::HTTP.get_response(uri)
puts res.body if res.is_a?(Net::HTTPSuccess)
json = JSON.parse(res.body)
cat = json&.first.dig("url") # аналогично json.first["url"], но с проверкой на nil
if cat
puts "Ваш котик по адресу: #{cat}"
else
puts "Ваш котик не найден"
end
Нашему приложению может понадобиться запрашивать данные у других веб-приложений (обычно по API). В этом примере мы получаем файл в формает json в ответе, но с помощью http запросов мы можем получать и другие форматы.
Пока для наших приложений мы будем формировать html, чтобы сразу показывать его в браузере. Но html - статический формат.
Как нам "вставить" руби-код в html-документ? Теоретически, мы можем формировать html в руби, как в примере, но это неудобно. С помощью erb (embedded ruby) - templating system for Ruby.
Выполним и разберём код из примера.
Пока просто попробуем сформировать html с помощью erb, в дальнейшем шаблоны будут храниться в отдельных файлах, так нам будет удобнее с ним работать.
binding - текущий контекст исполнения, он будет содержать переменные, методы и т.п., доступные в данный момент.
Теперь нужно сделать так, чтобы наш html стал доступен в браузере для наших пользователей (пока локально, у вас на компьютере :)
Rack предоставляет минималистичный интерфейс для разработки веб-приложений на Ruby, оборачивает http-запросы и ответы.
Rack provides a minimal, modular, and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the bridge between web servers, web frameworks, and web application into a single method call.
Definitive guide to rack - подробная статья о rack - что именно это значит.
Создадим файл config.ru Добавим в Gemfile сервер puma или thin:
gem "puma"
# или
gem "thin"
Установите: bundle install
Если возникают ошибки при установке этих гемов и не получается их решить, то есть альтернативный вариает запуска с помощью rackup:
Добавьте gem "rackup"
в Gemfile (вместо puma или thin), сделайте bundle install
.
Наше приложение будет соответствовать Rack-протоколу, сервера puma, thin и др. также соответствуют этому протоколу.
Puma/Thin ищут файл config.ru
в той же директории (где запускаем их) и используют его для запуска приложения.
Протокол rack (т.е. наше приложение должно содержать):
- метод
call
- принимает объект
env
(representing the HTTP request, ruby hash) - возвращает массив из трёх значений: the status code, the headers, and the response.
Пишем hello world на rack:
class App
def call(env)
headers = { 'content-type' => 'text/html' }
response = ['<h1>Greetings from Rack!!</h1>']
[200, headers, response]
end
end
run App.new
Запуск с помощью puma:
puma
Запуск с помощью thin:
thin
Запуск с помощью rackup:
bundle exec rackup config.ru
При запуске вы увидите примерно такой текст:
Puma starting in single mode...
* Puma version: 6.4.3 (ruby 3.3.0-p0) ("The Eagle of Durango")
* Min threads: 0
* Max threads: 5
* Environment: development
* PID: 27471
* Listening on http://0.0.0.0:9292
Use Ctrl-C to stop
Вы можете увидеть привет от rack (ответ, к-й мы сформировали) в браузере по адресу http://0.0.0.0:9292
Также можете зайти по адресам http://localhost:9292/ и http://127.0.0.2/
Также можете проверить ответ с помощью curl:
curl -v http://localhost:9292/
Пример проекта rack hello world
Напишем более осмысленное rack-приложение.
Чтобы каждый раз не перезапускать сервер вручную.
Добавьте в Gemfile gem "rerun"
Запуск приложения:
rerun puma
# c rackup
rerun bundle exec rackup
Возьмите код программы Magic Ball, которую мы писали на одной из прошлых занятий.
Перенесём код в наше rack-приложение. Таким образом, пользователи смогут заходить на наш сайт и получать ответ на вопрос, который они задумали, от магического шара.
На этом этапе вы можете оформить код по-разному:
- "положить" код получения ответа от шара прямо в код метода
call
- выделить код в отдельный метод
- создать класс
MagicBall
, положить логику туда и подключить в файлеconfig.ru
с помощью require
Можно сделать html немного красивее. Я подключила фреймворк simple.css для минимальной красоты.
Можете взять вот такой html, в к-й подставите ваш answer
.
html = <<~HTML
<html>
<head>
<meta charset='utf-8' />
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css" />
<title>Magic Ball</title>
<head>
<body>
<main><h1>#{answer}</h1></main>
</body>
</html>
HTML
Мой вариант в репозитории
Аналогично мы можем добавлять в наше приложение любой код, в т.ч. подключаться к базе данных, как на прошлом занятии, чтобы делать нужные фичи.
Пример подключения базы данных и отображения информации на странице
Для проверки отправьте код на github.
Напоминалка по созданию репозитория:
- создаёшь на гитхабе если без ридми создашь, по идее напишет инструкцию
- в директории git init
- добавляешь файлы - git add файлы (git add . - все файлы)
- коммитишь git commit -m "описание"
- git remote add origin url_репозитория (ssh)
- git push origin main
Поделитесь кодом :)
Создайте шаблон для ответа не с помощью интеполяции строк, а с помощью шаблонизатора erb, как в задании "Embedded Ruby".
(подключите "erb", сформируйте html, вместо вывода на экран отдайте html в response)
Definitive guide to rack - подробная статья о rack - что это, зачем нужен, и как с ним работают фреймворки.
Подробно: что происходит, когда вводим url в браузере
(This repository is an attempt to answer the age-old interview question "What happens when you type google.com into your browser's address box and press enter?")
Что происходит, когда вы вбиваете доменное имя в браузере
- упрощённая версия предыдущего текста на русском
Упражнение по erb Придумайте и напишите своё приложение с API из списка или других открытых API.