Play Framework (Scala)
Productivity Formula
by Sorin Chiprian
What is Play?
Play is a cool framework
Easy to learn
Play supports both Scala & Java
What do I like most
Best error reporting ever seen
Hit refresh and works
(this applies for configurations, templates or code changes)
What else?
Play is REST-ful
❖ Matches the web architecture which is stateless
➢ the state will be stored on the other tiers
(Cookie, Database,Cache Server)
❖ Easy testing, easy sharing, easy bookmarking
➢ an url is what you need
❖ Horizontal scalability
# Routes
# This file defines all application routes (Higher priority routes first)
GET / controllers.Application.index
GET /:timeout controllers.Application.asyncURLGet(timeout: Int, url:String)
GET /clients/$id<[0-9]+> controllers.Clients.show(id: Long)
GET /clients controllers.Clients.list(page: Int ?= 1)
GET /hello/:name controllers.Application.hello(name:String)
Play has a powerful URL rooting
➔ url should be established before coding
➔ more complicated routing can be achieved by extending
GlobalSettings or by defining your own Router
➔ even more can be done with PathBindable
➔ also possible to do reverse routing
routes.Application.hello("Bob")
Play has a very simple config
Play is a modern web framework
● application.conf
environment="development"
db.default.url = "jdbc:mysql://127.0.0.1:3306/mydb"
…
● production.conf
include "application.conf"
environment="production"
db.default.url = ${?MYSQL_URL}
Some Code Example
Request -> is the request performed by the client
Action -> something which converts a request into a response
Response -> Is the HTTP Response with Status Code, Cookies, Headers, Body
BodyParser -> a function that transforms the request body in a Scala (or Java) value, based on Content-Type of the
request
object Application extends Controller {
def index = Action {
Ok("It works!")
}
def hello(name: String) = Action {
Ok("Hello " + name)
}
}
GET / controllers.Application.index
GET /hello/:name controllers.Application.hello(name:String
The above example is not getting any reference from the incoming request, but we have another Action builder that takes as an
argument a function Request => Result:
def index = Action { request =>
Ok("Got request [" + request +
"]")
}
Simple example of serving a response
routes file
Action(parse.text) { request =>
val text = request.body
Ok("Got request " + text )
}
We can use a body parser in order to read the request.
In this example we will use the play.api.mvc.BodyParsers
parse.text -> parses the body as text if the Content-Type is text/plain.
Inside Play
Play has a MVC stack with a template system
Templates
Scala-based template engine
Template markup syntax
@(title: String, content: String)
<!DOCTYPE html>
<html>
<head>
<title>@title</title>
</head>
<body>
@content
</body>
</html>
Ok(views.html.main("title","content"))
Templates and assets are
compiled so any error will be
displayed immediately
app → Application sources
└ assets → Compiled asset sources
└ stylesheets → Typically LESS CSS sources
└ javascripts → Typically CoffeeScript sources
└ controllers → Application controllers
└ models → Application business layer
└ views → Templates
conf → Configurations files and other non-compiled resources
└ application.conf → Main configuration file
└ routes → Routes definition
public → Public assets
└ stylesheets → CSS files
└ javascripts → Javascript files
└ images → Image files
project → sbt configuration files
└ build.properties → Marker for sbt project
└ plugins.sbt → sbt plugins & declaration for Play itself
logs → Standard logs folder
└ application.log → Default log file
target → Generated stuff
test → source folder for unit or functional tests
myProject
Where is the fun?
Load Balancer
Play Server
Play Server
Play Server
This is what we have until now
- it’s cool but no fun -
This is fun !!!
Load Balancer
Play Server
Play Server
Play Server
Cloud Service
Memcache Service
Database
Cloud Storage
Cloud Service
Cloud Service
!!! The remote services latency in a threaded model could mean trouble !!!
Solving the issue
Play is built on top of Akka and Netty
➔ you can use non-blocking I/O when making calls to remote services
In high traffic environments, thread pools management is painful
❖ make threads on the fly
➢ This is expensive inefficient
❖ use a thread pool with too few threads
➢ run up of threads -> latency issues
❖ use a thread pool with too many threads
➢ context switching overhead
➢ Memory overhead
Play comes with a WS Library
WS.url(url).withHeaders("headerKey" -> "headerValue").get()
➔ request reading is also async
➔ enables:
◆ WebSockets
◆ Comet
Attention the database access most probably will not be async
Some async example
This can get even more fun
Play it’s production ready
Play is already being used by companies like:
Play is scalable
Instant deployment on
but you can found instruction for:
Cloudbees
Cloud Foundry
Clever Cloud
Some other features
Database evolutions
evolutions.use.locks=true
database locks are used to ensure that only
one host applies any Evolutions
# Users schema
# --- !Ups
CREATE TABLE User (
id bigint(20) NOT NULL
AUTO_INCREMENT,
email varchar(255) NOT NULL,
password varchar(255) NOT NULL,
fullname varchar(255) NOT NULL,
isAdmin boolean NOT NULL,
PRIMARY KEY (id)
);
# --- !Downs
DROP TABLE User;
when running on multiple hosts only use evolutions if you are using
Postgres or Oracle
Anorm, simple SQL data access
Plugins
classes that extend the Plugins trait
conf/play.plugins file
10000:my.example.FirstPlugin
10001:my.example.SecondPlugin
<priority>:<classname>
def enabled : Boolean
def onStart (): Unit
def onStop (): Unit
in
can overwrite the following methods
conf/evolutions/default/1.sql
conf/evolutions/default/2.sql
...
Dependency injection
Activator
Spring
Subcut
Macwire
Guice
val appDependencies = Seq( javaJpa, "org.hibernate" %
"hibernate-entitymanager" % "3.6.9.Final")
Unit testing
Junit -> java
Specs2 -> scala
integration with Selenium
No built-in JPA implementation in Play, but you can add
Hibernate
SQL("Select name,indepYear from Country")().map {
row =>
row[String]("name") -> row[Int]("indepYear")
}
What would you try
Java or Scala
try the samples folder

Play framework productivity formula

  • 1.
    Play Framework (Scala) ProductivityFormula by Sorin Chiprian
  • 2.
    What is Play? Playis a cool framework Easy to learn Play supports both Scala & Java
  • 3.
    What do Ilike most Best error reporting ever seen Hit refresh and works (this applies for configurations, templates or code changes)
  • 4.
    What else? Play isREST-ful ❖ Matches the web architecture which is stateless ➢ the state will be stored on the other tiers (Cookie, Database,Cache Server) ❖ Easy testing, easy sharing, easy bookmarking ➢ an url is what you need ❖ Horizontal scalability # Routes # This file defines all application routes (Higher priority routes first) GET / controllers.Application.index GET /:timeout controllers.Application.asyncURLGet(timeout: Int, url:String) GET /clients/$id<[0-9]+> controllers.Clients.show(id: Long) GET /clients controllers.Clients.list(page: Int ?= 1) GET /hello/:name controllers.Application.hello(name:String) Play has a powerful URL rooting ➔ url should be established before coding ➔ more complicated routing can be achieved by extending GlobalSettings or by defining your own Router ➔ even more can be done with PathBindable ➔ also possible to do reverse routing routes.Application.hello("Bob") Play has a very simple config Play is a modern web framework ● application.conf environment="development" db.default.url = "jdbc:mysql://127.0.0.1:3306/mydb" … ● production.conf include "application.conf" environment="production" db.default.url = ${?MYSQL_URL}
  • 5.
    Some Code Example Request-> is the request performed by the client Action -> something which converts a request into a response Response -> Is the HTTP Response with Status Code, Cookies, Headers, Body BodyParser -> a function that transforms the request body in a Scala (or Java) value, based on Content-Type of the request object Application extends Controller { def index = Action { Ok("It works!") } def hello(name: String) = Action { Ok("Hello " + name) } } GET / controllers.Application.index GET /hello/:name controllers.Application.hello(name:String The above example is not getting any reference from the incoming request, but we have another Action builder that takes as an argument a function Request => Result: def index = Action { request => Ok("Got request [" + request + "]") } Simple example of serving a response routes file Action(parse.text) { request => val text = request.body Ok("Got request " + text ) } We can use a body parser in order to read the request. In this example we will use the play.api.mvc.BodyParsers parse.text -> parses the body as text if the Content-Type is text/plain.
  • 6.
    Inside Play Play hasa MVC stack with a template system Templates Scala-based template engine Template markup syntax @(title: String, content: String) <!DOCTYPE html> <html> <head> <title>@title</title> </head> <body> @content </body> </html> Ok(views.html.main("title","content")) Templates and assets are compiled so any error will be displayed immediately app → Application sources └ assets → Compiled asset sources └ stylesheets → Typically LESS CSS sources └ javascripts → Typically CoffeeScript sources └ controllers → Application controllers └ models → Application business layer └ views → Templates conf → Configurations files and other non-compiled resources └ application.conf → Main configuration file └ routes → Routes definition public → Public assets └ stylesheets → CSS files └ javascripts → Javascript files └ images → Image files project → sbt configuration files └ build.properties → Marker for sbt project └ plugins.sbt → sbt plugins & declaration for Play itself logs → Standard logs folder └ application.log → Default log file target → Generated stuff test → source folder for unit or functional tests myProject
  • 7.
    Where is thefun? Load Balancer Play Server Play Server Play Server This is what we have until now - it’s cool but no fun -
  • 8.
    This is fun!!! Load Balancer Play Server Play Server Play Server Cloud Service Memcache Service Database Cloud Storage Cloud Service Cloud Service !!! The remote services latency in a threaded model could mean trouble !!!
  • 9.
    Solving the issue Playis built on top of Akka and Netty ➔ you can use non-blocking I/O when making calls to remote services In high traffic environments, thread pools management is painful ❖ make threads on the fly ➢ This is expensive inefficient ❖ use a thread pool with too few threads ➢ run up of threads -> latency issues ❖ use a thread pool with too many threads ➢ context switching overhead ➢ Memory overhead Play comes with a WS Library WS.url(url).withHeaders("headerKey" -> "headerValue").get() ➔ request reading is also async ➔ enables: ◆ WebSockets ◆ Comet Attention the database access most probably will not be async
  • 10.
    Some async example Thiscan get even more fun
  • 11.
    Play it’s productionready Play is already being used by companies like: Play is scalable Instant deployment on but you can found instruction for: Cloudbees Cloud Foundry Clever Cloud
  • 12.
    Some other features Databaseevolutions evolutions.use.locks=true database locks are used to ensure that only one host applies any Evolutions # Users schema # --- !Ups CREATE TABLE User ( id bigint(20) NOT NULL AUTO_INCREMENT, email varchar(255) NOT NULL, password varchar(255) NOT NULL, fullname varchar(255) NOT NULL, isAdmin boolean NOT NULL, PRIMARY KEY (id) ); # --- !Downs DROP TABLE User; when running on multiple hosts only use evolutions if you are using Postgres or Oracle Anorm, simple SQL data access Plugins classes that extend the Plugins trait conf/play.plugins file 10000:my.example.FirstPlugin 10001:my.example.SecondPlugin <priority>:<classname> def enabled : Boolean def onStart (): Unit def onStop (): Unit in can overwrite the following methods conf/evolutions/default/1.sql conf/evolutions/default/2.sql ... Dependency injection Activator Spring Subcut Macwire Guice val appDependencies = Seq( javaJpa, "org.hibernate" % "hibernate-entitymanager" % "3.6.9.Final") Unit testing Junit -> java Specs2 -> scala integration with Selenium No built-in JPA implementation in Play, but you can add Hibernate SQL("Select name,indepYear from Country")().map { row => row[String]("name") -> row[Int]("indepYear") }
  • 13.
    What would youtry Java or Scala try the samples folder