Обзор новых возможностей в playframework v2

в 9:14, , рубрики: java, play framework, scala, метки: , ,

Доброго времени суток всем. Хотел бы представить вашему вниманию небольшое описание новых возможностей Play 2. Речь в данной статье пойдет о play2 scala.

Для начала расскажу немного о себе и play. С 2008 по 2010 я работал в команде разработчиков play, тогда мы усиленно работали над коммюнитизацией play (версии 1.0 и 1.1). На данный монент я сменил команду но часто вижусь с моими прежними коллегами и продолжаю использовать play в большинстве проектов. Сам play вытек из одного проприетерного проекта, который мы реализовали для одного из крупнейших французских банков. Вообще, если кому интересно, я могу написать об истории play в отдельной статье.

Роль scala и java

Если раньше поддержка scala в play реализовалась в специальном модуле то начиная с версии 2, scala является полноправным членом фреймворка на ровне с java. Если быть точнее то можно сказать что многие кирпичики play 2 сделаны на scala и могут быть использованы в java.

Система построения проектов

Раньше в play была собственная система построения проектов реализованная в виде скриптов / классов на python, bash, batch. Позднее нашлись люди которые в конец осквернили мой любимый фреймворк и прикрутили к нему мувен (maven) в ввиде отдельного модуля. Теперь же вся система построения проектов строится на sbt + плагин play sbt (ну и немного bash, batch куда без них).

Консоль play

В новой версии play обзавелся настоящей консолью. Теперь у вас есть возможность компилировать, тестить, запускать ваш проект (итд) прямо из консоли. А в целом консоль play всего лишь надстройка над консолью sbt.

Контроллеры и действия

Теперь в play все ваши действия (actions) должны возвращать специальный тип — результат (result). В scala части для этого имеется специальный helper — action:

def index = Action {
  Ok(«Hello world!»)
}

Это простой пример использования действия. Поверьте мне у вас есть возможность выполнять куда более сложные манипуляции.

Рутирование (routes)

Во второй версии не избежал изменений и механизм рутирования. Теперь вам явно нужно указывать ваши параметры http для каждого действия в файле routes.

GET /       controllers.Application.index
POST /:id       controllers.Application.new1(id:Int)

Если вы проектируете рут-карту до создания действий и контроллеров вы можете столкнутся с ошибками компиляции, поскольку вы указали несуществующие действия. В таком случае вы можете воспользоваться предопределенными действием — TODO которое возвращает 503 в случае обращения.

object Application extends Controller {
  def index = TODO
  def new1(id: Long) = TODO
}

Вид

Как вы могли видеть в play 2 был реализован новый движок скриптов вида базирующийся все так же на scala и схожий с ASP.NET Razor. Движок очень мощный и одновременно простой в изучении.

Модель

В play 2 в качестве модели у вас есть возможность использовать просто jdbc или же Anorm или что либо другое, например ScalaQuery или же если постараться то jpa, чего я бы вам не рекомендовал. Если вам интересно то я мог бы вынести в отдельную статью введение в Anorm.

Интеграция с Akka

Вы не узнаете асинхронную часть в play 2, она была переделана с использованием Akka 2.0. Вы можете конфигурировать вашу actor систему непосредственно в файле конфигурации или же если вам не нравится встроенная actor система вы можете использовать любую другую систему.

akka.default-dispatcher.core-pool-size-max = 64
akka.debug.receive = on

У вас все так же имеется возможность запускать задачи асинхронно только теперь это делается не по средствам аннотаций а немного подругому, так сказать все более в духе dsl.

Akka.system.scheduler.schedule(0 seconds, 30 minutes, testМе, «ме»)

Асинхронный HTTP

Поскольку вся внутренняя архитектура play построена на netty то благодаря этому мы имеем доступ к таким замечательным возможностям как WebSocket или асинхронное использование протокола HTTP. Иногда вам нужно выполнить какую либо ресурсоемкую операцию в одном из ваших контроллеров, именно для таких ситуаций вам и пригодится async HTTP. Все что вам нужно сделать в данном случае — это изменить тип результата в вашем действии с SimpleResult на AsyncResult.

def index = Action {
  val promise = Akka.future { computation() }
  Async {
    promise.map(result => Ok(«Got result: » + result))
  }
}

Работа с json

Так же в play 2 были добавлены доморощенные API для работы с json, на мой взгляд не самые удобные. Чтение json еще куда не шло (в простых случаях) но вот конвертирование из объектов в json, на мой взгляд очень хромает.

Чтение:

((Json parse string) «node1»  «node2»).asOpt[String]

Построение:

Json toJson Seq(toJson(1), toJson(«Bob»), toJson(3), toJson(4))

Хотя у вас всегдя есть возможность использовать внешние библиотеки как и в ранних версиях play.

Global object

Global object выступает в роли бутстрап-класса для вашего приложения. Он может вклиниваться в такие события вашего приложения как onStart, onStop, onError, onActionNotFound итд. Это своего рода замена @OnApplicationStart и ко из async jobs play 1.*. Вот пример использования такого объекта:

object Global extends GlobalSettings {
 
  override def onStart(app: Application) {
    Logger.info(«Application has started»)
  }  
 
  override def onStop(app: Application) {
    Logger.info(«Application shutdown...»)
  }  
}

Тесты

Здесь скажу лишь по поводу части scala. Наконец то появилась возможность использовать стороннюю библиотеку для тестирования, а именно specs2 с поддержкой mockito. Помимо этого тестирование остается таким же удобным как и раньше.

Заключение

Данная статья представляет собой лишь поверхностный обзор возможностей фреймворка play 2. Если вам интересно то далее я могу представить вашему вниманию более детальные обзоры на такие темы как:

  • Anorm и другие light orm в play2
  • MVC play2 в детялях
  • Play2 в продакшене
  • Итд

Спасибо за внимание.

Автор: vba

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js