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
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
Play 3.0
- Reactive and Functional
- High productivity developer experience
- No global state!
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
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
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