Erlang для веб. Фреймворки.

2 августа 2014

Доклад для 3-й встречи Belarus Erlang User Group.

Что такое веб-фреймворк?

Для начала выясним, какие фичи обычно имеет типичный веб-фреймворк. Берем за основу самые популярные: Ruby on Rails и Django.

Теперь посмотрим, что из этих фич есть в веб-фреймворках для Erlang, а чего нет. И, наоборот, что в Erlang есть такого, чего нет в Rails и Django.

Chicago Boss

Первым заслуживает разговора этот фреймворк. Развитый, стабильный, неплохо документированный. Имеет много достоинств и мало недостатков :)

Автор Chicago Boss, Evan Miller, черпал вдохновение в Ruby on Rails. Он попытался сохранить идеологию Rails, и в какой-то мере их архитектуру. По мнению автора получилось лучше оригинала, ибо удалось сохранить все хорошее, и добавить к этому фичи Erlang :)

Автор, явный сторонник ООП, использовал параметризованные модули и parse transform, чтобы сделать код приложения похожим на ООП. Плюс, он скрыл от разработчика OTP-архитектуру, предлагая взамен MVC. Тем самым упростил порог входа для разработчиков, не знакомых с Erlang.

Известно, что Ruby on Rails, это отдельный мир. И хороший разработчик на рельсах совсем не обязательно хорошо знает Ruby и может на нем писать без рельс. Возможно, будь Chicago Boss более популярным, аналогичная ситуация могла бы сложиться и здесь :)

Вот пример кода:

-module(person, [Id, Name, Age]).

Person = person:new(id, "Joe", 4)
Person:validate()
Person:save()

Параметризованными модулями пронизан весь код, и на них нужно остановиться особо. Это экспериментальная, не рекомендуемая к использованию и не документированная фича Erlang, которая была в языке в версиях R13-R15. А в версии R16 ее убрали. Но добавили специальный parse transform, чтобы приложения, использующие эту фичу, все таки могли работать на R16. Подробнее тут. В итоге Chicago Boss без проблем работает на R16.

Раньше использовался веб сервер Mochiweb, сейчас Cowboy.

Код можно писать не только на Erlang, но и на Elixir, если хочется.

Фичи фреймворка

Роутинг

Ну понятное дело, какой веб-фреймворк может быть без ротинга? Можно пользоваться дефолтным, где по URL и по именам конроллеров определяется, какой из них нужно вызывать. И можно задавать свой, кастомный.

Сессии

Хранятся в ETS или в Mnesia. Авторизация и привязка запроса к сессии делаются до вызова контроллера. Для этого нужно задавать свой hook.

ORM

BossRecord, похожий на ActiveRecord из Rails. И BossDB, дающий общий интерфейс к разным базам данных. Поддерживаются MySQL, PostgreSQL, Riak, MongoDB, Tokyo Tyrant и Mnesia.

В какой-то мере поддерживается миграция и откат схемы БД.

Шаблоны

ErlyDTL шаблоны копируют синтаксис шаблонов Django. Компилируются в beam файлы (каждый шаблон в отдельный Erlang-модуль). Работают, по утверждению автора, очень быстро.

Их можно использовать отдельно от Chicago Boss.

Кеширование

Кеширование моделей реализовано как часть ORM. Кеширование шаблонов не нужно, они и так хранятся в оперативной памяти как скомпилированные Erlang-модули.

Emails

Хорошая поддержка работы с emails. Получение и отправка писем. Конечно с поддержкой ErlyDTL шаблонов.

Функциональные тесты

Свой фреймворк для создания и запуска функциональных тестов.

Кроме этого, Chicago Boss, опираясь на возможности Erlang, предлагает нетипичные для веб-фреймворков фичи.

BossMQ

Своя реализация message queue.

BossNews

Событийная модель, рассылка событий, подписка на события.

WebSocket и long-polling

Разумеется, с эффективностью, недоступной для Ruby/Python.

Чего нехватает

Нет автоматической генерации CRUD-операций из модели.

Формы не генерируются, нужно вручную делать шаблоны для них.

Функции валидации форм нужно писать вручную.

Нет генерации схемы БД из модели.

Так что тут не получится, как в Django, просто описав модель данных, сразу получить полноценный CRUD веб-интерфейс. Придется еще поработать ручками :)

UPD оказывается это есть Admin interface for Chicago Boss, просто не документировано.

Локализация в какой-то мере поддерживается, но я не вникал, не скажу подробностей.

Итого

Проект зрелый, развивается с 2010 года. > 1200 комитов, 54 контрибьютора.

В вики есть список сайтов, построенных на Chicago Boss. Там не густо. Но отметим среди них erlang-factory.com.

Самый развитый веб-фреймворк для Erlang. И лично я выбрал бы именно его.

Nitrogen

Нестандартный проект, который не пытается повторить фичи MVC фрейворков, а идет своим путем. Этот фреймворк предназначен не для сайтов, а для интерактивных веб-приложений.

Есть такой термин RIA - Rich Internet Applications. Вот именно для них. Это могут быть приложения типа facebook, с обновляемым в реальном времени контентом; чаты, игры, какие-нибудь бизнес-приложения с таблицами и графиками и т.д.

Идея в том, что сперва на клиент отдается html-страница, и с нее клиентский JS-код с помощью long-polling активно общаться с сервером. Клиентские события: нажатия на кнопку, перетаскивания и т.д. идут на сервер, с сервера идут данные и отображаются на клиенте.

Nitrogen предлагает свой DSL, построенный на record, для описания интерфейса средствами HTML и для связывания клиентских событий с обработчиками на сервере.

Работает поверх разных веб-серверов, в т.ч. поверх Cowboy.

Фичи фреймворка

Чего нет

Нету WebSockets, что, конечно, странно для такого проекта. Может я и ошибаюсь, но я не нашел инфы о том, что WebSockets поддерживаются.

Нет какой-либо работы с базой данных.

Нет готовых CRUD операций.

Его DSL-язык вынуждает программиста самому возиться с макетом, полученным от дизайнера. HTML-верстальщика не посадишь создавать интерфейс.

Итого

Это один из первых Erlang-фреймворков, начался в 2008 году. Но не такой активный, как Chicago Boss: > 800 commits, 24 контрибьютора.

Документирован неплохо: API, туторы, примеры. Но нет обзорной документации, описывающей идеологию и архитектуру.

Узкоспециализированный, нишевый продукт с ограниченными возможностями.

Имеет смысл использовать только если вам очень нравится его DSL. Иначе аналогичные приложения можно строить и без него, используя богатые клиентские JS-библиотеки, и REST API на сервере.

N2O

Фреймворк Nitrogen 2 Optimized – наследник Nitrogen. Создан Максимом Сохацким из Киева. Максим долгое время работал над крупным веб-проектом: социальной сетью с онлайн играми, и изначально использовал там Nitrogen. По ходу работы Nitrogen сильно дорабатывался, и по фичам, и по производительности, и по чистоте кода. В результате практически полностью был переписан.

Разумеется, N2O использует WebSockets. Позволяет подключить любой клиентский JS-фреймворк и свой JS-код. Позволяет использовать вместо Nitrogen DSL другие шаблоны (ErlyDTL например).

И предлагает несколько своих библиотек:

KVS – общий интерфейс к noSQL/key-value базам данных. Из которых сейчас поддерживаются Mnesia, RIAK и KAI. (Реляционные базы не поддерживаются самой идеологией этой библиотеки.)

AVZ – библиотека авторизации через Facebook, Google, Twitter, Github, Microsoft.

MQS – библиотека для RabbitMQ.

Есть и другие.

Итого, сейчас нет причин использовать оригинальный Nitrogen, и для RIA проектов лучше брать N2O.

Zotonic

Про Zotonic пару слов.

Это веб-фреймворк и CMS, но, похоже, больше CMS, нежели фреймворк. И сравнивать его нужно скорее с Drupal или Joomla, чем с Rails :)

Ну нормальная такая CMS с обычными для такого рода продуктов фичами. Но обещает большую скорость и стабильность.

Проект старый, с 2009 года.

Итого: не знаю, для кого это. Но раз проект живет, значит он кому-то нужен :)

Выводы по фреймворкам

ChicagoBoss предлагает сравнительную таблицу фич разных фремворков. Познавательно :)

Ну так что мы имеем?

Один неплохой классический MVC фреймворк: ChicagoBoss.

Один фреймворк для RIA приложений: N2O (использовать оригинальный Nitrogen вроде бы нет причин).

Одна кому-то нужная CMS: Zotonic.

Однако эти фреймворки не пользуются особой популярностью даже среди Erlang-программистов. И причины тут понятны: на Erlang просто не делают таких проектов, где был бы нужен MVC-фреймворк, CRUD, ORM и т.д. Потому, что эти проекты проще делать на Rails, Django и т.д. Есть разработчики, есть большой опыт, есть много успешных проектов. Erlang можно использовать в таких проектах для каких-то специфических целей, дополняя, а не заменяя Rails/Django. Что и делается в компании, где я работаю.

Пару слов о моих веб-проектах на Erlang

У меня есть 3 веб-проекта на Erlang, разной сложности, с разными подходами. Не знаю, можно ли их назвать “типовыми”, но как пример использовать можно.

Проект №1

Многопользовательская онлайновая игра.

iOS клиент с постоянным TCP-соединением. Со стороны сервера Ranch Acceptor Pool. Bert-сериализация данных.

Flash-клиент. Со стороны сервера cowboy, json-сериализация.

Веб-админка, показывающая различную статистику и позволяющая управлять разными настройками. Cowboy, ErlyDTL шаблоны, самодельная валидация форм. Работа с базой напрямую, голый SQL.

Тут можно было бы применить ChicagoBoss, а можно и не применять, админка простая.

Проект №2

Информационный веб-ресурс. Сложная структура базы данных, сложные запросы, большей частью SELECT. Запросов, модифицирующих базу, мало. Однако нужна админка с полноценными CRUD операциями ко всем объектам в базе.

Админка сделана на Django/Python, схема базы (MySQL) сгенерирована из Django-модели. Пользовательская часть: Cowboy, голые SQL запросы, хранение сессий в Memcache, XSL шаблоны.

Для такого проекта ChicagoBoss можно использовать. Но в компании уже существовало некое свое решение на Erlang, не фреймворк, но архитектурный подход и набор библиотек. Которое мне и предложили использовать и развивать дальше. Это решение меня в целом устраивает, за исключением XSL шаблонов. Очень уж они корявые и многословные. Но с шаблонами я сам не работаю, работает верстальщик, и он это умеет. Если бы с шаблонами нужно было работать мне самому, я бы настаивал на ErlyDTL.

Проект №3

Ну это главный проект компании: онлайн кинотеатр tvzavr.ru.

Он сделан на Python/Django/MySQL. Сложный проект, с большой кодовой базой. Код там может и не самый красивый, но архитектурно сделано все довольно грамотно. Так, что сейчас есть пространство для маневра, если нужны доработки и оптимизации производительности. А они нужны постоянно :)

Одним из важных решений было разделение контента страницы на общий, одинаковый для всех пользователей, и индивидуальный для каждого пользователя. Общий контент страницы рендерится питоном из шаблона, отдается пользователю, и кешируется на уровне nginx. Индивидуальный контент запрашивается браузером отдельно, JS-запросами к веб АПИ.

В итоге есть две системы: основной сайт и веб АПИ. Которые можно развивать и оптимизировать независимо друг от друга. Они связаны через базу, и через Memcache (где хранятся сессии и другие важные данные).

Веб АПИ изначально тоже было на питоне. Но сейчас где-то половина его, наиболее нагруженная, переписана на эрланге. И я делаю следующую версию АПИ уже целиком на эрланге.

comments powered by Disqus