play24-sneak-peak



play24-sneak-peak

0 0


play24-sneak-peak


On Github jroper / play24-sneak-peak

Play 2.4 - A sneak peak

James Roper

Partnership with IBM

  • Play will be backed by WebSphere AS
  • Play colors change from green to blue
  • Improved compiler
    • Code written while not wearing a blue tie is a syntax error

A look into the past

Play 1.0

  • Django/Ruby on Rails clone for Java
  • Heavily relied on global state

Play 2.0

  • Reactive and Functional
  • High productivity developer experience
  • Inherited global state from Play 1

Global state

  • Primarily comes down to play/api/Play.scala:73:
      @volatile var _currentApp: Application
  • Makes testing difficult

A look into the future

Play 3.0

  • Reactive and Functional
  • High productivity developer experience
  • No global state!

The current: Play 2.4

Dependency Injection

State of DI in Java

  • General approach: solved
  • Which DI framework: hotly debated

State of DI in Scala

  • General approach: hotly debated

Options for DI in Scala

  • Runtime Injection (Guice, Spring etc)
  • Compile time injection
    • Cake pattern
    • Implicit wiring
    • Macro based tools
    • Reader Monad
    • Manual constructor wiring

How can we make everyone happy?

DI principles in Play 2.4

  • Plain old constructors/factory methods
  • Provide abstraction to use any runtime DI provider
  • Provide one runtime DI provider out of the box
  • Provide helpers for compile time injection out of the box

Backwards compatibility

  • Where possible, deprecate rather than delete
  • Allow DI code to exist alongside static code

Runtime DI

  • Provide Guice by default
  • Use JSR330 annotations for wiring
  • Provide a binding abstraction to allow other DI providers

Compile time DI

  • Provide an implementation of the lightweight cake pattern

Testing

Unit testing

  • Is now possible without abstracting over Play APIs
  • Mock dependencies by injecting them into the component
  • Use familiar tools such as mockito

Integration testing

  • Multi component integration testing
    • Testing some components together
    • In isolation from the application
    • Does not start a Play application
    • Simpler, less fragile tests
  • Full integration testing
    • Starts a Play application

Testing with databases

  • Programatic instantiation of connection pools
  • Programatic applictaion of evolutions
  • No running application required

Testing with databases in Scala

Database.withDatabase(
  driver = "com.mysql.jdbc.Driver",
  url = "jdbc:mysql://localhost/test"
) { database =>
  val connection = database.getConnection()
  // ...
}

Testing with databases in Java

Database database;

@Before
public void createDatabase() {
    database = Database.createFrom(
            "com.mysql.jdbc.Driver",
            "jdbc:mysql://localhost/test"
    );
}

@After
public void shutdownDatabase() {
    database.shutdown();
}

Testing with mocked webservices

  • Embeds webservices in tests
  • Full HTTP client test
  • No running application required

Mocked webservices in Scala

Server.withRouter() {
  case GET(p"/repositories") => Action {
    Results.Ok.sendResource("gh/repos.json")
  }
} { implicit port =>
  WsTestClient.withClient { client =>
    val gitHub = new GitHubClient(client, "")
    val result = await(gitHub.repositories())
    result must_== Seq("octocat/Hello-World")
  }
}

Mocked webservices in Java

Server server = Server.forRouter(new RoutingDsl()
    .GET("/repositories").routeTo(() ->
            ok().sendResource("gh/repos.json")
    )
    .build()
);

Full integration testing

  • Dependent on the DI provider
  • GuiceApplicationBuilder
    • Override configuration
    • Override modules
    • Override individual bindings

Overriding bindings in Scala

import play.api.inject.bind

val cache = mock[Cache]

val application = new GuiceApplicationBuilder()
  .bindings(bind[Cache].toInstance(cache))
  .build

Overriding bindings in Java

import static play.inject.Bindings.bind;

Cache cache = mock(Cache.class);

Application application = new GuiceApplicationBuilder()
    .bindings(bind(Cache.class).toInstance(cache))
    .build();
);

DI wrap up

  • Pathway towards removing global state
  • Something for everyone
  • Biggest advantage is testing

Advance questions

Akka HTTP

  • Experimental support in Play 2.4
  • Most Play integration tests passing
  • No performance testing done yet

Enabling Akka HTTP

lazy val root = (project in file("."))
  .enablePlugins(PlayScala, PlayAkkaHttpServer)
  .disablePlugins(PlayNettyServer)

Reactive Streams

  • Experimental support in Play 2.4
  • Provides iteratee/enumerator implementions of subscribers/publishers
  • No performance tuning has been done yet
  • Play 3 will replace iteratees with reactive streams

Java 8

  • Play 2.4 requires JDK 8
  • Some JDK 8 APIs in use for Java API
  • All Java documentation now uses lambdas

Unified authentication/authorization

  • We're taking a similar approach to Spring with Acegi/Spring Security
  • Silhouette looks interested, 2.0 released the other day

Other build tools

  • Work done by LinkedIn to support Gradle
  • Work done by Play community to make Play more build tool agnostic
  • Typesafe will only officially support sbt
  • sbt configuration option to switch back to a standard Maven/SBT project layout

HikariCP

  • Play 2.4 makes HikariCP the default connection pool
  • BoneCP still available and straight forward to use

Resources