Статьи

Учимся создавать Clojure Webapps

Некоторое время назад я выступил на внутреннем мероприятии в Zenika Singapore. Мы были свободны в выборе темы, поэтому я выбрал что-то, о чем, как мне казалось, я недостаточно знал — каково это — создавать веб-приложение в Clojure. Этот пост является стенограммой выступления. Я подробно расскажу о Clojure, о том, какие библиотеки вы можете использовать для создания веб-приложений, и как все это чувствовало ко мне.

Clojure

Clojure — это диалект LISP, предназначенный для JVM, Microsoft CLR и JavaScript с помощью ClojureScript. Это функциональный и динамичный язык. Одна из его особенностей — неизменные структуры данных, которые полагаются на структурное совместное использование при добавлении или удалении элементов. Это обеспечивает хорошую производительность даже при сохранении неизменности.

Я в основном заинтересовался Clojure, потому что

  • это очень отличается от всех языков на основе C вокруг
  • все еще будучи языком общего назначения

Благодаря некоторым своим функциям, таким как программная транзакционная память (STM) и атомы, она особенно хорошо подходит для создания правильных параллельных приложений.

Один аспект, который я считаю важным: это, кажется, довольно дружелюбное сообщество, и мне понравились обе группы пользователей, в которых я принимал участие, Clojure Berlin и Clojure Meetup Singapore .

Если вы хотите начать работу с Clojure, лучше всего начать с очень распространенного инструмента сборки Leinigen . Среди прочего, он предлагает простой способ создания и запуска проектов, автономный или в REPL, функция, которая обычно используется с диалектами LISP.

Одного использования REPL и Leiningen вам будет недостаточно, по крайней мере, вам нужно что-то для редактирования файлов. Естественно, многие люди, похоже, используют emacs, кроме того, что есть также Cursive (построенный на IntelliJ), Lighttable (экспериментальная IDE) и Nightcode (очень простой редактор со встроенным REPL).

Чтобы начать работу с проектом, вы можете просто установить Leiningen и начать, запустив REPL с помощью lein repl .

Давайте начнем с простой операции, добавив два числа.

1
2
user=> (+ 2 3)
5

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

1
2
user=> (+ 2 3 4 5)
14

И если подумать: это совсем не так уж необычно. Если вы видите + как имя функции (что это такое), это очень похоже на то, как вы бы вызывали функцию на языке, подобном ac.

1
plus(2, 3, 4, 5)

Конечно, вы также можете присвоить результат вычисления переменной.

1
2
3
4
5
6
user=> (def result (+ 2 3 4 5))
#'user/result
user=> result
14
user=> (- result 1)
13

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

Также очень легко создавать функции.

1
2
3
4
user=> (defn append-mod [val] (str val "-mod"))
#'user/append-mod
user=> (append-mod "some-value")
"some-value-mod"

Более интересными структурами данных являются коллекции. Есть векторы для последовательных данных.

1
2
3
4
5
6
user=> (def characters ["a" "b" "c"])
#'user/characters
user=> (characters 0)
"a"
user=> (characters 1)
"b"

И есть карты, часто используемые с так называемыми ключевыми словами в качестве ключей.

1
2
3
4
user=> (def my-map {:key "value" :foo "bar"})
#'user/my-map
user=> (my-map :key)
"value"

Будучи функциональным языком, очень часто выполняется преобразование коллекций, например, с помощью операции map. Это также показывает использование функций в качестве граждан первого класса, как видно из передачи в upper-case функции.

1
2
userer=> (map clojure.string/upper-case characters)
("A" "B" "C")

Важно: это не изменяет существующую коллекцию — она ​​создает новую. Все возможно благодаря эффективной реализации структур данных.

проблемы

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

  • (defn name [] (body))
  • (def name (fn [] (body)))
  • #(body)

Одна вещь, которая все еще трудна для меня, это решить, как структурировать программы в Clojure. Кажется распространенным, чтобы в одном и том же пространстве имен было много функций. Я предполагаю, что трудно решить, какая функция отвечает за какие данные или задачу.

Наконец, по крайней мере для меня, документы могут сбивать с толку.

Создание веб-приложений

В качестве языка общего назначения Clojure, конечно, может использоваться и часто используется для создания веб-приложений. По сравнению с Java-ландшафтом выбора гораздо меньше, очень распространенной комбинацией является использование трех библиотек: Ring в качестве базовой библиотеки, Compojure для маршрутизации и Hiccup для шаблонизации.

Кольцо реализовано в виде конвейера. Сначала есть адаптер, который используется для сопоставления с внутренним представлением запроса / ответа и который адаптируется к существующей веб-среде выполнения. Существует адаптер, использующий Jetty, или другой, который использует только API сервлетов, что позволяет развертывать приложение Ring в любом контейнере сервлета.

Далее идут промежуточные программы. Это как фильтры в мире сервлетов Java и могут быть использованы для улучшения приложения. По умолчанию некоторые промежуточные программы настроены, например, для обработки параметров, сеанса или файлов cookie.

В конце запрос попадает в обработчик, который преобразует запрос в ответ.

Compojure может помочь вам реализовать маршрутизацию для этих обработчиков. Это простой пример, который создает один успешный маршрут и одну функцию для обработки путей, которые не найдены.

1
2
3
(defroutes app
  (GET "/" [] "<h1>Hello World</h1>")
  (route/not-found "<h1>Page not found</h1>"))

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

1
lein new compojure my_project_name

Это создаст необходимую структуру папок, файл leiningen, обработчик и тест для него.

Если вы не хотите писать все html в Strings самостоятельно, как в примере выше, пришло время для библиотеки шаблонов. Тот, который часто используется в сочетании с Ring и Compojure — это Hiccup. Это позволяет вам писать код Clojure, который переводится в HTML.

1
2
user=> (html [:span {:class "foo"} "bar"])
"<span class="\"foo\"">bar</span>"

Я разработал очень простое приложение с использованием этих библиотек: инструмент для просмотра и добавления словарного запаса. После запуска вы можете увидеть список слов, добавить больше слов и посмотреть переводы. Я бы не сказал, что он готов к производству, одна из причин в том, что он хранит все данные только в памяти 🙂 Вы можете найти исходный код на Github .

Он содержит GET и POST маршрут для чтения списка и добавления слова и шаблона Hiccup.

Вывод

Работать над новым языком было весело, и после понимания основ Clojure было легко начать работу с веб-приложением, в основном благодаря шаблону Leiningen Compojure, который облегчает настройку нового проекта. В промежуточном программном обеспечении Ring доступно множество готовых функций. Hiccup все еще кажется мне немного странным, я не слишком уверен, что многие разработчики веб-интерфейсов заинтересованы в работе с ним.

Хотелось бы, чтобы у меня было больше времени, чтобы подготовить доклад и поработать над примером. Есть еще много вещей, о которых я понятия не имею, и я надеюсь, что смогу найти время, чтобы продолжить обучение. Несмотря на то, что я не планирую использовать Clojure в проекте на работе в ближайшее время, очень полезно узнать о новых подходах — ваше восприятие некоторых языковых функций может измениться.

Если вы хотите начать работать и с Clojure — я могу особенно рекомендовать серию Aphyrs по основам . В течение многих лет я видел полезную лекцию разных людей из InnoQ, которая особенно касается веб-библиотек. Запись Майкла Витца доступна на YouTube .

Смотрите оригинальную статью здесь: Учимся создавать Clojure Webapps

Мнения, высказанные участниками Java Code Geeks, являются их собственными.