Мы все знаем о Ruby on Rails, и большинство из нас знает о Sinatra. Но есть процветающая экосистема небольших веб-фреймворков для Ruby, помимо этих двух.
Не пойми меня неправильно; Синатра потрясающая! Я использовал это несколько раз в прошлом, и это было здорово. Тем не менее, важно узнать об альтернативных подходах к той же проблеме.
Получите преимущество, установив рамки, которые мы расскажем: «Gem Install Cuba Camping»
В этой статье мы рассмотрим несколько микрофреймов в Ruby, которые используют два существенно разных подхода, сравнивают их и выясняют их целевые варианты использования.
Куба
Куба — это микрофрейм, который, наверное, мой любимый по ряду причин, которые мы увидим довольно быстро.
Давайте начнем с примера приложения, которое они предоставляют:
require «cuba» | |
Cuba.use Rack::Session::Cookie | |
Cuba.define do | |
on get do | |
on «hello» do | |
res.write «Hello world!» | |
end | |
on root do | |
res.redirect «/hello» | |
end | |
end | |
end |
Допустим, вы сохранили это в «hello_cuba.rb»
Это довольно простой код, но он многого добился. Cuba.define принимает блок, в котором мы можем использовать метод «on», которому мы передаем «get».
Затем внутри другого блока мы можем определить маршруты, которые отвечают на запросы.
Однако, чтобы запустить это, вы не можете просто набрать «ruby hello_cuba.rb». Вместо этого приложения Кубы запускаются с помощью Rack. Rack — это интерфейс, который позволяет Руби общаться с веб-сервером.
Чтобы это работало, вам нужен файл config.ru (там же, где и файл hello_cuba.rb):
require «./hello_cuba» | |
run Cuba |
Теперь, чтобы выполнить всю эту сделку, наберите «rackup» в своем терминале (или, iTerm, Konsole, Powershell; здесь мы не судим), и у вас должен быть запущен сервер (вероятно, через порт 9292).
Перейдите по адресу http: // localhost: 9292 /, и вы должны будете перенаправлены на / hello (проверьте строку URL), и в вашем браузере должно появиться приятное сообщение «Hello, world!».
Вы могли бы подумать, что вся эта сделка с рэкпаком довольно бессмысленна, но когда вы развертываете приложение, это облегчает жизнь.
Это становится интересным, когда вы пытаетесь написать тесты для приложений Кубы. Проверьте это:
require «cuba/test» | |
scope do | |
test «Homepage» do | |
get «/» | |
follow_redirect! | |
assert_equal «Hello world!», last_response.body | |
end | |
end |
Исходя из Синатры, я думаю, что это невероятно! Куба имеет встроенную поддержку для написания краткого, чистого кода для тестов. Тесты — это отчасти мой рабочий процесс кодирования (они тоже должны быть вашими!), Поэтому я считаю это очень удобным. Как вы можете видеть, мы запускаем запрос, следим за перенаправлением и проверяем ответ (конечно, вы, вероятно, не будете делать такие вещи на очень больших страницах, но это работает здесь).
Давайте напишем еще один код соответствия URL:
require «cuba» | |
Cuba.use Rack::Session::Cookie | |
Cuba.define do | |
on get do | |
on «hello» do | |
res.write «Hello world!» | |
end | |
on «echo/:string» do |string| | |
res.write string | |
end | |
on «print», param(«p») do |string| | |
res.write string | |
end | |
on root do | |
res.redirect «/hello» | |
end | |
end | |
on.post do | |
on «api» do | |
res.write ‘{«error» : «no api yet»}’ | |
end | |
end | |
end |
Мы добавили запрос post, который возвращает довольно бесполезный JSON, и добавили пару методов GET. Почтовые маршруты работают как положено; на пост сделать, и, пошли.
Маршрут / echo /: string очень прост — вы можете перейти к чему-то вроде localhost: 9292 / echo / rubysource, и он выведет «rubysource». Маршрут / print делает то же самое, за исключением параметров URL. Проверьте синтаксис — вам действительно нужно определить, что вы будете использовать из параметров, прежде чем блок начнет свой путь. Я лично думаю, что это помогает мне, для других, им может просто понравиться хэш параметров.
Куба также обладает всевозможными функциями безопасности. Все, что вам нужно сделать, чтобы получить к ним доступ, это добавить «Cuba.use Rack :: Protection» вверху кода приложения. Это предотвращает большинство атак с вами! Он даже поставляется со встроенной поддержкой шаблонов ! Это то, чего мне очень не хватает в других небольших рамках, и я люблю Кубу за это. Это делает жизнь очень легкой (это просто вызов рендера).
Философия Кубы состоит в том, чтобы написать веб-приложение в виде пары файлов, причем большая часть всего глобального (так же, как Синатра).
Я использовал Кубу для самых разных вещей, таких как одностраничное приложение в реальном времени для небольшого приложения для выставления счетов. Это сработало очень хорошо для меня. Тем не менее, ошибки в производительности трудно отследить, и разделение кода не должно быть там.
На следующей микрорамке!
Поход
Кемпинг придерживается принципиально иной философии, чем Синатра и Куба — это система MVC. Философия Кэмпинга говорит, что вместо того, чтобы объединять все вместе, гораздо лучше хранить вещи отдельно, но все же, в одном файле.
Вот супер крошечное приложение в кемпинге:
Camping.goes :Hello | |
module Hello::Controllers | |
class Index < R ‘/’ | |
def get | |
p «Hello, world!» | |
end | |
end | |
end |
Вы можете сохранить его как «hello_camping.rb» и запустить его командой «camp hello_camping.rb» (при условии, что вы установили кемпинг, как вы должны иметь в начале статьи), который должен запустить сервер через порт 3301. Если Вы скользите по порту 3301 с помощью браузера, вы должны увидеть «Hello, world!», справедливо и квадратно.
Код немного сложнее, чем на Кубе, но это не так уж плохо. Сначала мы сообщаем Camping о том, что наши модули будут проходить, что приводит к строке Camping.goes: Hello, затем мы определяем модуль, в котором будут определены классы контроллера.
В нашем примере у нас только один контроллер — Index
Index
R '/'
Внутри у нас есть метод, который отвечает на запрос GET и распечатывает ответ.
В кемпинге есть что-то под названием Markaby bake прямо сейчас — это в основном DSL в Ruby, так что разметка может быть сгенерирована путем вызова методов Ruby. Проверьте это:
Camping.goes :Hello | |
module Hello::Controllers | |
class Index < R ‘/’ | |
def get | |
render :hello | |
end | |
end | |
end | |
module Hello::Views | |
def hello | |
html do | |
head do | |
title «Hi, world!» | |
end | |
h1 «Hello, world!» | |
h3 «Bye, world!» | |
end | |
end | |
end |
Мы определили новый модуль Hello::Views
Мы можем визуализировать эти представления из контроллера, как мы это сделали. Итак, это часть View-Controller MVC готова к работе!
Запустив это (опять же, «кемпинг filename.rb») и указав ваш браузер в правильном направлении, вы должны получить хорошую пару заголовков вместе с набором заголовков. Markaby DSL является удивительно полным и очень полезным, но для более крупных проектов я все же предпочитаю HAML, ERB или Liquid.
Маршруты в кемпинге довольно просты (прямо из путеводителя):
module Nuts::Controllers | |
class Words < R ‘/welcome/to/my/site’ | |
def get | |
«You got here by: /welcome/to/my/site» | |
end | |
end | |
class Digits < R ‘/nuts/(\d+)’ | |
def get(number) | |
«You got here by: /nuts/#{number}« | |
end | |
end | |
class Segment < R ‘/gorp/([^/]+)’ | |
def get(everything_else_than_a_slash) | |
«You got here by: /gorp/#{everything_else_than_a_slash}« | |
end | |
end | |
class DigitsAndEverything < R ‘/nuts/(\d+)/([^/]+)’ | |
def get(number, everything) | |
«You got here by: /nuts/#{number}/#{everything}« | |
end | |
end | |
end |
Как видите, основной метод обработки маршрутов — регулярные выражения. Я использовал это в прошлом с такими фреймворками, как Django в Python, но я не нахожу это столь привлекательным для быстрых проектов, как маршруты в стиле Синатра / Куба. В конце концов, это ваш выбор, и регулярные выражения могут быть гораздо более мощными.
Существует альтернативный способ сопоставления маршрутов (с шаблонами в именах классов контроллеров), но я обнаружил, что эта система очень глючная и более болезненная, чем она того стоит. Если вы хотите использовать его, ознакомьтесь с документами .
Говоря о документах, у Camping, вероятно, есть самые превосходные документы, которые я видел для любой веб-среды, кроме Flask (которая основана на Python). Несмотря на то, что они не дошли до безумной глубины, их легко читать и очень быстро вас оценивают, поэтому я настоятельно рекомендую вам проверить их.
Одной из самых крутых особенностей кемпинга являются модели. Вот пример:
Camping.goes :People | |
module People::Models | |
class Person < Base | |
end | |
class BasicFields < V 1.0 | |
def self.up | |
create_table Person.table_name do |t| | |
t.string :first_name | |
t.string :last_name | |
t.text :description | |
t.timestamps | |
end | |
end | |
def self.down | |
drop_table Person.table_name | |
end | |
end | |
end | |
def People.create | |
People::Models.create_schema | |
end |
На самом деле это не полноценное веб-приложение (поскольку у нас нет контроллеров или представлений), но мы можем поиграть с ним в консоли.
Однако до этого давайте посмотрим на код. В модуле People :: Models есть классы, в которых мы храним как миграции, так и модели. Модели должны прийти до миграции. Что касается миграций, если вы знаете, как они работают в Rails, вы знаете, как они работают здесь. По сути, части запросов к базе данных Rails (ActiveRecord) повторно используются в Camping, поэтому большая часть интерфейса одинакова.
Миграции имеют номера версий, определенные производным от класса «V», поэтому вы можете составлять миграции друг за другом, указав последовательные номера версий.
Чтобы поиграть с этим, запустите camping -C filename.rb
Вот что удивительно — при запуске консоли создается база данных и выполняется миграция!
Что касается использования консоли, если вы использовали консоль Rails (что является лучшей вещью после нарезанного хлеба), интерфейс будет очень похожим. Кроме того, чтобы ссылаться на модели, вы должны использовать «People :: ModelName», поэтому в нашем случае «People :: Models :: Person». Интересно попробовать следующие вещи:
#makes life much easier | |
Person = People::Models::Person | |
#gives all current Persons | |
Person.all | |
#add me, then search for me | |
dhaivat = Person.new(:first_name => «Dhaivat», :last_name => «Pandya», :description => «Best person ever») | |
dhaivat.save | |
Person.all | |
Person.find(1) | |
Person.where(:first_name => «Dhaivat») |
Сравнивая Кемпинг с Кубой, он имеет совершенно другую идеологию с точки зрения разделения интересов. Много раз, когда один из них будет работать лучше, чем другой в некоторых наборах приложений. В большинстве случаев для небольших проектов это не имеет значения — выбирайте то, что вам удобно.
Мне очень нравится Camping за его невероятно простое взаимодействие с базами данных. С Кубой это сложнее, так как вы должны использовать внешнюю библиотеку, такую как DataMapper. Кроме того, включенное преимущество отличной консоли действительно замечательно для выявления ошибок.
Я обычно использую Camping для небольших проектов, для которых я мог бы использовать Rails, но у меня мало времени и я хочу, чтобы разработка делалась быстро. Я использовал это несколько раз для проектов выходного дня и тому подобное.
Завершение
Надеюсь, вам понравился вихревой тур по двум абсолютно превосходным микрофраморам, которые были разработаны с огромным вниманием.
Я нашел эти фреймворки действительно полезными, и я попытался включить некоторые из их идей в другие технологии, с которыми я работаю (например, Rails).
Спасибо и оставьте отзыв!