Міжнародная канферэнцыя распрацоўнікаў і карыстальнікаў свабодных праграм

Применение Clojure в web-разработке

Дмитрий Бушенко, Минск, Belarus

LVEE Winter 2013

Clojure is a modern dialect of Lisp intentionally designed for seamless integration with the JVM-platform. Due to its functional nature and Lisp flexibility, Clojure suits well for web-applications development. A lot of of libraries written in functional style make web-development with Clojure really simple.

В 2007 году был представлен язык программирования Clojure1, быстро завоевавший популярность в кругах любителей Lisp-а и функциональнй парадигмы. Автор языка, Рич Хикки, был недоволен существовавшими на то время реализациями Lisp-а в основном из-за того, что они плохо интегрировались с существующими платформами. Кроме того, в диалектах Lisp-а, стандартизированных несколько десятков лет назад, содержится много устаревших технологий и синтаксиса.

Язык Clojure создавался для того, чтобы преодолеть указанные недостатки. Clojure обладает более удобным и современным синтаксисом, максимально ориентирующим пользователя на функциональную парадигму. Несмотря на динамическую типизацию языка, программы на Clojure компилируются в jvm-байткод и бесшовно интегрируются с существующими java-программами. Сейчас Clojure реализован уже для нескольких платформ, наиболее заметные из которых: JVM, .NET и JavaScript.

Язык Clojure является также и выражением идей Рича Хикки о том, насколько простым должен быть инструмент разработчика. В Clojure обычно используются всего четыре структуры данных (список, вектор, отображение и множество), вокруг которых построен основной API. Основная абстракция языка Clojure — это чистая функция, не имеющая побочных эффектов и, таким образом, гораздо больше приспособленная для повторного использования.

На сегодняшний день для Clojure написано большое количество библиотек2, в том числе и для разработки веб-приложений. Они пропитаны духом Clojure, философией простоты и модульности. В мире Clojure не приветствуются фреймворки, ведь конкурирующие фреймворки отвратительно сочетаются вместе в одном приложении. Программа на Clojure — это конструктор с открытой архитектурой, в которой никто не навязывает вам выбор каких-то библиотек только из-за того, что вы прежде выбрали уже другие. Например, Java-программисты с трудом связывают вместе Spring, Guice и JEE, если вообще берутся за такое. Но что если вам нравится какая-то часть одного фреймворка, и какая-то другого? Разве вам не хотелось бы использовать их оба вместе?

В Clojure для каждого архитектурного уровня есть множество альтернатив, среди которых вы можете выбрать одну или несколько библиотек сразу (рис. 1).


Рис. 1. Библиотеки Сlojure для различных модулей архитектуры веб-приложения.

Уровень маршрутизатора реализуют библиотеки Ring, Compojure и Moustache.

Ring — это практически голый сервлет, каким он был бы, если бы его написали в функциональном стиле3. Центральная абстракция этой библиотеки — handler, который обрабатывает request и создает response (рис. 2). И request, и response — это обычные структуры данных Clojure — отображения. Композиция из функций-middleware и handler-ов задают бизнес-логику обработки запроса. Как видите, это строгий функциональный подход.


Рис. 2. Ring

Mustache и Compojure — это небольшие надстройки над Ring, каждый из которых по-своему упрощает отображение маршрутов на функции, их обрабатывающие.

Уровень доступа к данным представлен несколькими интересными библиотеками, наиболее заметные из которых — это Korma и ClojureQL.
Korma — это библиотека, декларирующая, что она все-таки не ORM4. Учитывая функциональную природу программ на Clojure, Object-Relational Mapping-у здесь и впрямь взяться неоткуда. Результаты запросов к БД представлены в виде векторов и отображений, а сами запросы записываются на удобном предметно-ориентированном языке, внешне сильно напоминающем SQL.

ClojureQL схожа с Korma в том, что это предметно-ориентированный язык5. Но, в отличие от Korma, семантика ClojureQL ближе к чистой реляционной алгебре, нежели к SQL.

Уровень представления реализуется целым рядом библиотек, соответствующих современным тенденциям. Hiccup — это то, как выглядел бы Haml, если бы его изначально написали на Clojure6. Clostache — это порт Mustache на Clojure, а clj-soy — порт Google Closure Templates. Особенного внимания заслуживает библиотека Enlive, аналогов которой по сути и нету7. Она сильно напоминает XSLT т.к. занимается преобразованием исходного html-файла по заданным правилам. Но, в отличие от XSLT, у которого громоздкий, неудобный синтаксис, Enlive делает все кратко и элегантно.
Важной частью инфраструктуры программ на Clojure является ClojureScript — реализация Clojure, компилирующегося в JavaScript8. Для ClojureScript также существует несколько шаблонизаторов, самые заметные из которых — Dommy9 и Enfocus10 (порт Hiccup и Enlive на ClojureScript). Использование Clojure на всех уровнях, начиная от доступа к БД, заканчивая UI-логикой, позволяет отказаться от целого ряда лишних действий. Например, нет нужды генерировать ORM-привязки к таблицам БД, очень упрощается передача данных с сервера на клиент, отпадает необходимость во всех промежуточных протоколах вроде SOAP или JSON.

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

Таким образом, язык Clojure очень хорошо подходит для разработки web-приложений. Он обладает отличной инфраструктурой, бесшовно интегрируется с любым java-кодом и может деплоиться на стандартных серверах приложений java. Гибкость языка Clojure и его потрясающая выразительность позволяют создавать web-приложения за минимальное время.

Ссылки

1 Clojure, http://clojure.org
2 Clojure Toolbox, http://www.clojure-toolbox.com
3 Ring, https://github.com/ring-clojure/ring
4 Korma, http://sqlkorma.com
5 ClojureQL, http://www.clojureql.org
6 Hiccup, https://github.com/weavejester/hiccup
7 Enlive, https://github.com/cgrand/enlive
8 ClojureScript, https://github.com/clojure/clojurescript
9 Dommy, https://github.com/Prismatic/dommy
10 Enfocus, http://ckirkendall.github.com/enfocus-site

Abstract licensed under Creative Commons Attribution-ShareAlike 3.0 license

Назад