Исторически сложилось, что Groovy берет много хорошего у Ruby. В первую очередь, конечно Grails (от Rails), но и Spock (от Spec) и даже где-то Gradle (от Buildr, хотя никто не признается). Сегодня я вам расскажу про еще одну толковую «спертую» штуку — web framework Ratpack.
![image](https://habrastorage.org/r/w780q1/getpro/habr/post_images/d1e/882/b8c/d1e882b8c4835a6c2c16448e047b1510.jpg)
Списан Ratpack с Sinatra, о котором много написано на Хабре, например вот тут.
На мой взгляд, главное преимущество Синатры —что он талантливый певец что это простейший в использовании и моментальный в разработке фреймворк. Создать несколько простых страниц, менять их и видеть результаты налету, и за несколько часов сваять достаточно нетривиальный сайт с динамическим контентом — это как раз то, для чего и был придуман Синатра. Это, своего рода, ответ «ожиревшим» Рельсам. Точно в такой же роли (ответа «ожиревшим» Грейлзам) Синатра и перекочевал в Груви.
Должен заметить, что на сей раз сообщество Груви были не первыми, кто передрал Синатру. Первыми были Scala, со своей Скалатрой (ага, ответ на «ожиревший» Play). Насколько я знаю, решение не делать название похожим на слух, а искать ассоциацию по смыслу, было принято в первую очередь, придя в ужас от звучания названия версии Скалы :)
Ratpack переводится на русский как Крысиная стая, и привязка к Синатре в том, что это тусовка, в которой тусовался Франк Синатра.
Ну, тут, мне кажется, все ясно. В отличие от Руби, где когда-то был lightweight RoR, или от Груви с его Грейлз, в Джаве никогда не было мейнстримных «легковесных» фреймворков*. У нас есть либо громоздкие server-side component фреймворки типа JSF и Wicket, либо MVC фреймворки, которые, конечно, легче компонентных монстров, но все равно, требуют нагородить MVC для простейшей странички. Тут, конечно, я говорю о Spring MVC и Struts2. И всё это с жутко медленным циклом разработки «поменял слово? перезагрузи!». Бррр.
Как справедливо заметил antonarhipov, можно воспользоваться фреймворками для REST APIs, такими как Jersey и RESTlet, но это, на мой взгляд, абьюз.
В Джаве уже есть клон Синатры, который называется Spark, так почему бы не воспользоваться им? Я вижу для этого несколько причин:
Как всегда, преимущество Груви для программистов Джава — что они чувствуют себя как дома. 99% Java кода работает в Грувях без изменений, поэтому любой Груви фреймворк или инструмент может быть немедленно использован Java программистом.
Ситуация и с ratpack еще лучше — разработчики специально постарались, чтобы можно было писать на чистой Джаве, не задействуя Груви ни на одном этапе разработки. Таким образом вы можете начать не зная о Груви ничего, и потихоньку открывая для себя фичи Ratpack-а, начать писать на Груви. Один из примеров в этой статье будет написан 100% на Java. Кого на первом этапе не интересует всё это Грувийное шаманство, перекручивает прямо на последний пример. Остальные начинают здесь:
Ну, я думаю, начать надо с Hello, World!, правда? Полноценное веб-приложение на ratpack выглядит так:
Всё. Честно. Пишем это в файл (например ratpack.groovy), запускаем через
Послушно идем на
![](https://habrastorage.org/r/w1560/storage2/399/7f9/a77/3997f9a77cacb5b3f7b99885078124fe.png)
Давайте посмотрим, что же мы написали:
Вписываем в наш ratpack.groovy еще один обработчик:
Файл сохраняем, в браузере идем на
![](https://habrastorage.org/r/w1560/storage2/513/1f5/795/5131f579547af56c1ebb5aab7987af01.png)
Перезагружать? Нееее, это не для нас. Кто молодец? Spring-loaded молодец.
Прибавим скорости и интересу. Код:
Результат:
![](https://habrastorage.org/r/w1560/storage2/069/03c/1f3/06903c1f356768c653b86ac372850f70.png)
Ну, или так. Код:
Результат:
![](https://habrastorage.org/r/w1560/storage2/daa/a62/3fa/daaa623fa88caa422c3fd14719a836c0.png)
Можно упомянуть еще о многих интересных фичах, но статья уже и так не короткая, а я еще будет пример на чистой Джаве, поэтому давайте посмотрим на работу с шаблонами. Для примера возьмем Groovy template:
Шаблоны лежат в директории
Скрипт с обработчиком теперь выглядит так:
Обратите внимание на новый static import.
Результат ожидаем:
![](https://habrastorage.org/r/w1560/storage2/76c/30d/2c1/76c30d2c12b23569be3840efaca81379.png)
Ну, тут не будет запускаемого скрипта, и не ждите. Тут будет серьезное приложение, со структурой директорий, модулями, с файлом сборки.
Dependency injection будет на Guice, веб-сервер на netty, сборка и запуск на gradle, перезагрузка с помощью Spring-loaded.
Поехали:
Структура проекта:
![](https://habrastorage.org/r/w1560/storage2/4a6/9e4/bf6/4a69e4bf6a3935d9f038513fa2ff301e.png)
Файл ratpack.properties говорит кто есть
Класс
Да, Java 8 не помешал бы.
Тут все похоже на Грувийную версию — добавляем обработчик на путь hello/:username, потом берем значение динамической части пути из
Запускаем task-ом
![](https://habrastorage.org/r/w1560/storage2/d9e/d76/bd7/d9ed76bd7a4e378ca768348ea41070ff.png)
Результат:
![](https://habrastorage.org/r/w1560/storage2/26b/a21/065/26ba21065ce2acf581351b679f6593c7.png)
Честно говоря, Java пример получился не очень привлекательным. Нагородили классов и директорий, когда это все можно написать в 4 строчках Груви. Так зачем?
Преимущества Джавы начинаются при росте в сложности и размере. Внезапно, разделение на классы и пакеты, жесткое типизирование и возможность тестов становятся намного важнее количества файлов и строк. Чтобы увидеть эти преимущества, посмотрите на более полный пример Java приложения на Ratpack вот тут. Я уверен, вы поймете о каких преимуществах я говорю.
Естественно, это самые основы, естественно, в Ratpack есть намного больше плюшек, чем я сейчас показал. Это и модули Guice-а, и сервисы, и интеграция с MongoDB и с GORM-ом.
Использование Java классов для обработчиков, модулей и сервисов дает возможность создавать модулярное и легко тестируемое приложение средней сложности.
Использование Groovy скриптов дает возможность гораздо более быстрой разработки чего-либо простого, «на коленке», с впечатляющими результатами.
Я надеюсь, что сумел заинтересовать вас этим фреймворком. Как вы могли заметить, даже первая версия еще пока не вышла (хотя уже скоро), поэтому я бы не стал переписывать на него mission-critical приложения, но он достоин того, что обратить на него внимание, и попробовать наваять на нем вашу следующую «жуткую домашнюю страничку»
Если вы хотите продолжения, пишите в комменты.
Если вы хотите пообщаться на счет Ratpack-а лично, а так-же послушать про другие интересные штуки, приходите на JUG 31-го августа.
![image](https://habrastorage.org/getpro/habr/post_images/d1e/882/b8c/d1e882b8c4835a6c2c16448e047b1510.jpg)
Списан Ratpack с Sinatra, о котором много написано на Хабре, например вот тут.
На мой взгляд, главное преимущество Синатры —
Должен заметить, что на сей раз сообщество Груви были не первыми, кто передрал Синатру. Первыми были Scala, со своей Скалатрой (ага, ответ на «ожиревший» Play). Насколько я знаю, решение не делать название похожим на слух, а искать ассоциацию по смыслу, было принято в первую очередь, придя в ужас от звучания названия версии Скалы :)
Ratpack переводится на русский как Крысиная стая, и привязка к Синатре в том, что это тусовка, в которой тусовался Франк Синатра.
А причем тут Java?
Ну, тут, мне кажется, все ясно. В отличие от Руби, где когда-то был lightweight RoR, или от Груви с его Грейлз, в Джаве никогда не было мейнстримных «легковесных» фреймворков*. У нас есть либо громоздкие server-side component фреймворки типа JSF и Wicket, либо MVC фреймворки, которые, конечно, легче компонентных монстров, но все равно, требуют нагородить MVC для простейшей странички. Тут, конечно, я говорю о Spring MVC и Struts2. И всё это с жутко медленным циклом разработки «поменял слово? перезагрузи!». Бррр.
Как справедливо заметил antonarhipov, можно воспользоваться фреймворками для REST APIs, такими как Jersey и RESTlet, но это, на мой взгляд, абьюз.
В Джаве уже есть клон Синатры, который называется Spark, так почему бы не воспользоваться им? Я вижу для этого несколько причин:
- Freemarker или Velocity для темплейтинга. Первый, конечно, не так ужасен, как второй, но тоже не подарок. Оба хуже, чем Groovy Templates
- Hot Swap — клон Синатры должен уметь «поменял, F5, увидел». Если нет, то увы.
- Ratpack — прекрасная возможность плавно погрузиться в Груви. И я считаю, это главное преимущество.
Как всегда, преимущество Груви для программистов Джава — что они чувствуют себя как дома. 99% Java кода работает в Грувях без изменений, поэтому любой Груви фреймворк или инструмент может быть немедленно использован Java программистом.
Ситуация и с ratpack еще лучше — разработчики специально постарались, чтобы можно было писать на чистой Джаве, не задействуя Груви ни на одном этапе разработки. Таким образом вы можете начать не зная о Груви ничего, и потихоньку открывая для себя фичи Ratpack-а, начать писать на Груви. Один из примеров в этой статье будет написан 100% на Java. Кого на первом этапе не интересует всё это Грувийное шаманство, перекручивает прямо на последний пример. Остальные начинают здесь:
Hello, World!
Ну, я думаю, начать надо с Hello, World!, правда? Полноценное веб-приложение на ratpack выглядит так:
@GrabResolver('http://oss.jfrog.org/artifactory/libs-snapshot') //(1)
@Grab('org.ratpack-framework:ratpack-groovy:0.9.0-SNAPSHOT')
import static org.ratpackframework.groovy.RatpackScript.ratpack
ratpack { //(2)
handlers {
get {
response.send 'Hello, world!' //(3)
}
}
}
Всё. Честно. Пишем это в файл (например ratpack.groovy), запускаем через
groovy ratpack.groovy
:INFO: Ratpack started for localhost:5050
Послушно идем на
localhost:5050
и обнаруживаем там ожидаемое:![](https://habrastorage.org/storage2/399/7f9/a77/3997f9a77cacb5b3f7b99885078124fe.png)
Давайте посмотрим, что же мы написали:
- Это инструкция скачать все необходимые библиотеки с бесплатного opensource аккаунта Artifactory
- Это объявление приложения, оно состоит из обработчиков и модулей
- Это обработчик команды get. Поскольку у него нет параметров, он отработает по вызову root url. Тут-то мы и просим вернуть Hello World.
Добавляем еще один handler
Вписываем в наш ratpack.groovy еще один обработчик:
ratpack {
handlers {
get {
response.send 'Hello, world!'
}
get('habr'){
response.send 'Hello, habr!' //наш новый обработчик
}
}
}
Файл сохраняем, в браузере идем на
localhost:5050/habr
, наслаждаемся.![](https://habrastorage.org/storage2/513/1f5/795/5131f579547af56c1ebb5aab7987af01.png)
Перезагружать? Нееее, это не для нас. Кто молодец? Spring-loaded молодец.
Добавим динамизьму
Прибавим скорости и интересу. Код:
ratpack {
handlers {
get('hello/:username') {
response.send "Hello, ${pathTokens.username}"
}
}
}
Результат:
![](https://habrastorage.org/storage2/069/03c/1f3/06903c1f356768c653b86ac372850f70.png)
Ну, или так. Код:
ratpack {
handlers {
get('hello') {
response.send "Hello, ${request.queryParams.username}"
}
}
}
Результат:
![](https://habrastorage.org/storage2/daa/a62/3fa/daaa623fa88caa422c3fd14719a836c0.png)
Подключаем шаблоны
Можно упомянуть еще о многих интересных фичах, но статья уже и так не короткая, а я еще будет пример на чистой Джаве, поэтому давайте посмотрим на работу с шаблонами. Для примера возьмем Groovy template:
Шаблоны лежат в директории
templates
. Сохраним там, например, index.html
со следующим содержанием:<html>
<head>
<title>${model.title}</title>
</head>
<body>
<h5>${model.content}</h5>
<br/>
<img src="http://habr.habrastorage.org/post_images/9a5/14b/49a/9a514b49a2017e50f386f154c8cb0da2.png"/>
</body>
</html>
Скрипт с обработчиком теперь выглядит так:
@GrabResolver('http://oss.jfrog.org/artifactory/libs-snapshot')
@Grab('org.ratpack-framework:ratpack-groovy:0.9.0-SNAPSHOT')
import static org.ratpackframework.groovy.RatpackScript.ratpack
import static org.ratpackframework.groovy.Template.groovyTemplate
ratpack {
handlers {
get {
render groovyTemplate("index.html", title: 'Привет Хабру от Ratpack', content: 'Тут логотипы:')
}
}
}
Обратите внимание на новый static import.
Результат ожидаем:
![](https://habrastorage.org/storage2/76c/30d/2c1/76c30d2c12b23569be3840efaca81379.png)
Кто ждал Джавы? Их есть у нас!
Ну, тут не будет запускаемого скрипта, и не ждите. Тут будет серьезное приложение, со структурой директорий, модулями, с файлом сборки.
Dependency injection будет на Guice, веб-сервер на netty, сборка и запуск на gradle, перезагрузка с помощью Spring-loaded.
Поехали:
Структура проекта:
![](https://habrastorage.org/storage2/4a6/9e4/bf6/4a69e4bf6a3935d9f038513fa2ff301e.png)
Файл ratpack.properties говорит кто есть
HandlerFactory
(откуда брать обработчиков):handlerFactory=example.HandlerFactory
Класс
example.HandlerFactory
является, натурально factory для обработчиков. У нас там только один, Hello, %username%
:package example;
import ...
public class HandlerFactory implements org.ratpackframework.launch.HandlerFactory {
public Handler create(LaunchConfig launchConfig) {
return chain(new Action<Chain>() {
public void execute(Chain chain) {
chain.add(get("hello/:username", new Handler() {
public void handle(Context context) {
Map<String, String> pathTokens = context.getPathTokens();
context.getResponse().send("Hello from Java, " + pathTokens.get("username"));
}
}));
}
});
}
}
Да, Java 8 не помешал бы.
Тут все похоже на Грувийную версию — добавляем обработчик на путь hello/:username, потом берем значение динамической части пути из
context.getPathTokens()
.Запускаем task-ом
run
, перекомпилируем изменения task-ом classes
(в другом окне, run
останавливать не надо):![](https://habrastorage.org/storage2/d9e/d76/bd7/d9ed76bd7a4e378ca768348ea41070ff.png)
Результат:
![](https://habrastorage.org/storage2/26b/a21/065/26ba21065ce2acf581351b679f6593c7.png)
Честно говоря, Java пример получился не очень привлекательным. Нагородили классов и директорий, когда это все можно написать в 4 строчках Груви. Так зачем?
Преимущества Джавы начинаются при росте в сложности и размере. Внезапно, разделение на классы и пакеты, жесткое типизирование и возможность тестов становятся намного важнее количества файлов и строк. Чтобы увидеть эти преимущества, посмотрите на более полный пример Java приложения на Ratpack вот тут. Я уверен, вы поймете о каких преимуществах я говорю.
Заключение
Естественно, это самые основы, естественно, в Ratpack есть намного больше плюшек, чем я сейчас показал. Это и модули Guice-а, и сервисы, и интеграция с MongoDB и с GORM-ом.
Использование Java классов для обработчиков, модулей и сервисов дает возможность создавать модулярное и легко тестируемое приложение средней сложности.
Использование Groovy скриптов дает возможность гораздо более быстрой разработки чего-либо простого, «на коленке», с впечатляющими результатами.
Я надеюсь, что сумел заинтересовать вас этим фреймворком. Как вы могли заметить, даже первая версия еще пока не вышла (хотя уже скоро), поэтому я бы не стал переписывать на него mission-critical приложения, но он достоин того, что обратить на него внимание, и попробовать наваять на нем вашу следующую «жуткую домашнюю страничку»
P.S.
Если вы хотите продолжения, пишите в комменты.
Если вы хотите пообщаться на счет Ratpack-а лично, а так-же послушать про другие интересные штуки, приходите на JUG 31-го августа.