Наступило лето, пора отпусков, самое время заняться изучением Perl и Dancer, а также написать об этом пост (мой первый на хабре). Очертим круг читателей, которым он может быть полезным и интересным:
Всем любителям Perl.
Веб-разработчикам.
Всем, кто собирается писать на Perl.
Предисловие
Некоторое время назад мне встретилась (на полке заброшенных книг):
Она про версию языка 5.14, но что очень удобно для изучения Перла - код, работающий 15 лет назад, работает и сегодня. Многие примеры всё ещё применимы, а всё устаревшее улавливается и гуглится.
А ещё она написана прекрасным живым языком, легко читается и просто поднимает настроение.
Однако, если вы хотите начать изучение Perl сегодня, то лучше выбрать самое последнее, буквально на днях вышедшее, 8-е издание (все полезные ссылки будут в конце). Поправка: книга "Learning Perl, 8th Edition" написана, отправлена в печать, но ещё не выпущена. Амазон честно пишет "This title has not yet been released").
Язык мне очень понравился своей свободой и гибкостью. И я влюбился, влюбился с первой строчки кода, с первого цикла и первого модуля.
Перл и Web
На сегодняшний день существуют два основных фреймворка для web-разработки на PERL:
Dancer2
- микро-фреймворк, расширяется плагинами.Mojolicious
- полновесный фреймворк с большим количеством встроенных возможностей.
Оба поддерживаются и обновляются, авторы отвечают на вопросы и участвуют в коммуникации с сообществом. А ещё на странице каждого можно найти гайды и туториалы.
Я решил препарировать Dancer.
С чего начать
Было бы неплохо обзавестись последней версией языка, в этом поможет perlbrew
для Nix'ов и berrybrew
для Windows (или используйте менеджер пакетов вашей системы: deb, rpm, другие), и утилитой cpan(поставляется вместе с perl) для установки модулей и зависимостей.
Теперь ставим фреймворк:
cpan Dancer2
После установки, в наше распоряжение попадает утилита dancer2, которая создаст базовый скелет приложения:
dancer2 gen -a MyApp
bin - там лежит стартующий файл для запуска Dancer
lib - наш код
public - всё, что доступно из интернета
views - представления
t - тесты
environments - конфиги
config.yml - основной конфиг
cpanfile - зависимости (оказался очень полезным, расскажу в продолжении)
Makefile.PL - для зависимостей и размещения на cpan
MANIFEST.SKIP - для зависимостей и размещения на cpan
MANIFEST - для зависимостей и размещения на cpan
.dancer - для cpan
Теперь запустим тестовый сервер с помощью утилиты plackup(она была установлена вместе с фреймворком):
cd MyApp # директория проекта
plackup -p 5000 bin/app.psgi # запускаем сервер
Открыв http://localhost:5000, вы увидите там справочную страницу dancer с полезными ссылками и базовой информацией о вашем приложении:
Dancer2
Dancer2 реализует MVC, правда из коробки не предоставляет инструментов для работы с моделью(это уже реализуется с помощью плагинов). Для работы с представлениями предлагаются движки на выбор. Имеется множество адаптеров ко всем популярным модулям, что позволяет выбрать оптимальный для вас вариант.
Фрейморк предоставляет в пользование набор команд, которые выглядят как ключевые слова(спасибо гибкости Perl), но на самом деле являются функциями-хелперами. Из этих слов выстраивается доменно-специфический язык (DSL), который позволяет декларативно описывать логику:
use Dancer2;
get '/' => sub {
return 'Hello World!';
};
start;
Приложение имеет три файла конфигов. Config.yml в корне для всех основных настроек: сессии, куки, шаблоны. И два файла environments/development.yml и environments/production.yml. Первый используется по дефолту при запуске приложения и предназначен для разработки: очень подробное логирование почти всего процесса, вывод логов в консоль и отображение ошибок. Второй: логирование в файл, отключенные ошибки, задействуется в боевой среде и подключается с помощью ключа --env при запуске:
plackup -p 5000 --env production bin/app.psgi
Роутинг
Описываются роуты в файле lib/MyApp.pm с помощью специальных "http глаголов": get, post, put, delete и других, соответствующих основным http методам. Далее идет схема маршрута(роут) и анонимная функция-обработчик, куда будет передано управление при совпадении маршрута:
get '/' => sub {
return "Let's dance!";
};
Оператор жирной запятой (=>) может ввести в заблуждение людей незнакомых с языком. В Perl он эквивалентен обычной запятой (,) и в данном случае используется лишь для удобочитаемости при разделении аргументов функции get
.
В схеме можно описать именованные параметры, обозначив их двоеточием (:), с их помощью реализуются маршруты с динамическими фрагментами:
get '/pages/:page' => sub {
my $page = route_parameters->get('page');
return "Welcome to the page:$page";
};
Dancer позволяет дополнительно задать тип этого параметра в квадратных скобках([]). Этой возможностью надо пользоваться чуть ли не всегда, ведь улучшается не только читаемость, но и надежность кода:
get '/pages/:page[Int]' => sub {
my $page = route_parameters->get('page');
return "Welcome to the page:$page";
};
При попытке открыть http://localhost:5000/pages/main увидим стандартную 404:
Если вы повторяли за мной, то уже заметили некоторое неудобство. Вносимые изменения в код не подхватываются приложением до перезагрузки сервера. Это можно исправить, добавив ключ -R с указанием директории для наблюдения при запуске:
plackup -p 5000 -R lib bin/app.psgi
Теперь при обновлении кода в директории lib сервер будет автоматически перезапущен.
Шаблоны
Шаблоны располагаются в директории views и имеют расширение .tt. Подключаются они с помощью функции template
, которая первым аргументом принимает путь, а вторым переменные, которые надо ему передать:
get '/pages/:page[Int]' => sub {
my $page = route_parameters->get('page');
template 'page.tt', {
page => $page,
};
};
Создадим views/page.tt:
<h1>Hi!</h1>
<p>You are on page: <b><% page %></b></p>
Обратиться к переданным переменным можно, используя синтаксис <% var %>
.
Открываем http://localhost:5000/pages/12 и находим там:
Заметили, что на на странице имеются стили и картинки, которые мы нигде не описывали? Это базовый макет, который по дефолту создал для нас dancer2 views/layouts/main.tt. Можно его смело менять или создать свой. Только не забудьте изменить название в config.yml.
Итоги
Кажется, что информации для первой статьи более чем достаточно. Планирую продолжить серию и рассказать про: подключение к БД, выбор шаблонного движка, деплой, установку зависимостей, перенос приложения в docker. Если это вам интересно, вы знаете, что делать. Спасибо за внимание!
Серия статей про Dancer2
Часть I (текущая) - установка, роутинг и шаблоны
Часть II - выбор шаблонного движка, сессии и флэш-сообщения
Часть III - работа с базой, модели и миграции
Ссылки
Комментарии (23)
berez
06.08.2021 19:39plackup -p 5000 bin/app.psgi # запускаем сервер
А сервер при этом какой используется? Апач/нгинх или свой, перловый,дырявый?knutov
07.08.2021 12:05из https://metacpan.org/dist/Plack/view/script/plackup:
If no option is given, plackup will try to detect the best server implementation based on the environment variables as well as modules loaded by your application in
%INC
plackup
- это просто запускалка. Сервер по умолчанию, в большинстве случаев - этоStarman
. Всего их есть много, для разных задач и на любой вкус - https://plackperl.orgРазумеется, в продакшене перед этим следует ставить что-то типа
nginx
.alex_p007 Автор
09.08.2021 18:35Всё правильно. Ставим перед перловым сервером nginx. Об этом расскажу в одной из слудующих частей, когда дойдем до докера.
zmc
07.08.2021 05:49Делал как-то sql-over-http для Oracle базы, так ни один из языков прослойки (python/php/lua) не смог отдать полностью бооольшой выхлоп от базы. Только DBI-Oracle смог справиться с этой задачей как и N-цать лет назад..
PrinceKorwin
07.08.2021 14:57Вообще странно. Использование курсоров, фетчинг данных пачкой и что стримить в респонз + flush - этого должно быть достаточно и доступно во всех наверное языках, кто имеет коннекторы к Ораклу.
Разве что с их подсистемой памяти (GC) могут быть нюансы.
NiceDay
07.08.2021 22:10не знаю как там с другими языками, но в случае с php вам как минимум нужно
отключить буфферизацию в PDO (или какой там драйвер вы используете)
отключить буфферизацию ответа самого php (ob_... функции)
отключить буфферизацию сервера (например, для nginx
fastcgi_buffering off;)
вы уверены, что выполнили хотя бы эти действия?
zmc
08.08.2021 06:22вы уверены, что выполнили хотя бы эти действия?
Только буферизацию nginx'а.
Я не буду спорить в части специфики языков и тюнинга, возможно все так как Вы пишите. DBI-Oracle то же куча крутилок о назначении которых я ни чего не знаю, но он просто работает в дефолтном виде.
PrinceKorwin
08.08.2021 12:53Это не специфика языка, но библиотек и фреймворков. При чем здесь сам язык? :)
zmc
09.08.2021 07:11Да-да, язык тут не причем, а то что либа/фрэймворк пишется под язык и по стандартам языка - это не то.
Или что, я могу взять DBD/DBI модуль работы с базой от perl'а и заюзать его в python/php, или наоборот?
zmc
07.08.2021 17:06Тем не менее это факт, можете сами проверить. Да и не забывайте, что Oracle сама по себе оооочень странная BD. Так что, рановато ещё perl хоронить — откапывайте.
PrinceKorwin
07.08.2021 18:23Здесь Oracle не причем. Дело либо в драйвере к нему, либо в клиентском коде.
Он у вас, случайно, не остался?
zmc
08.08.2021 07:19Здесь Oracle не причем.
Ни кто не утверждал что он причем. Странная СУБД Oracle - это да, но не ....
Дело либо в драйвере к нему, либо в клиентском коде.
Ну да, ну да. libclntsh.so во всех случаях одна и та же. Код проще некуда: connect/preparee/execute и последующий json. Но виноват кто угодно только не язык реализации коннектора.
Из тех кто завелись с первого раза и без каких либо вопросов/твиков - это DBI-Perl и JDBC. Возиться и подкручивать что то в драйвере языка-реализации(кроме lua, с ним повозился) не было ни желания ни времени, а с java'ой я не очень дружу. Да и DBI-Oracle просто работает.
P.S.
Сильно разочаровал lua, так как окружение openresty, то хотелось обойтись штатными средствами, но видать не судьба.
PrinceKorwin
08.08.2021 12:56С первого раза завелись DBI-Perl и JDBC потому как это "тупые клиенты" к БД.
А в Python и PHP вы использовали фреймворки поверх них с кучей функционала. И этот функционал заточен под другие основные сценарии. Тем не менее, с помощью конфигурации можно и ваш запрос реализовать.
zmc
09.08.2021 07:18С первого раза завелись DBI-Perl и JDBC потому как это "тупые клиенты" к БД.
Что значит "тупые клиенты", почитайте POD по DBD/DBI, ознакомьтесь хотя бы с 10% его функционала что бы такое утверждать.
Тем не менее, с помощью конфигурации можно и ваш запрос реализовать.
Я не знаю какие танцы с бубном возле либы у вас практикуются, но у нас хоца что бы просто работало, а вот если где-то что-то неординарное, то можно и покрутить, но не наоборот.
PrinceKorwin
09.08.2021 11:39Я на DBI-Perl довольно активно лет 10 программировал если что. Знаю на сколько он "туп".
но у нас хоца что бы просто работало
Тогда вас стоит просто взять нужный инструмент в руки. Он есть в каждом языке :)
zmc
09.08.2021 13:22Я на DBI-Perl довольно активно лет 10 программировал если что
Чет по этому поводу большие сомнения. Проверять же не будем?
PrinceKorwin
09.08.2021 21:13Вы знаете... У меня нет никакого желания откапывать эту стюардессу :) хотя в своё время было весело, да.
mitya_k
09.08.2021 18:56В свое время Dancer был первым моим фреймворком на Perl(а он был первым промышленным языком). Сколько воды утекло...
PrinceKorwin
Ваш логотип прочитал сначала как Perl Danger. После прочтения статьи понял, что не ошибся.