Play framework productivity formula

13
Play Framework (Scala) Productivity Formula by Sorin Chiprian

description

Play framework

Transcript of Play framework productivity formula

Page 1: Play framework   productivity formula

Play Framework (Scala)

Productivity Formula by Sorin Chiprian

Page 2: Play framework   productivity formula

What is Play?

Play is a cool frameworkEasy to learn

Play supports both Scala & Java

Page 3: Play framework   productivity formula

What do I like mostBest error reporting ever seen

Hit refresh and works(this applies for configurations, templates or code changes)

Page 4: Play framework   productivity formula

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.confenvironment="development"

db.default.url = "jdbc:mysql://127.0.0.1:3306/mydb"

● production.confinclude "application.conf"

environment="production"

db.default.url = ${?MYSQL_URL}

Page 5: Play framework   productivity formula

Some Code Example

Request -> is the request performed by the clientAction -> something which converts a request into a responseResponse -> Is the HTTP Response with Status Code, Cookies, Headers, BodyBodyParser -> 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.BodyParsersparse.text -> parses the body as text if the Content-Type is text/plain.

Page 6: Play framework   productivity formula

Inside Play

Play has a MVC stack with a template system

TemplatesScala-based template engineTemplate 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 → Templatesconf → Configurations files and other non-compiled resources └ application.conf → Main configuration file └ routes → Routes definitionpublic → Public assets └ stylesheets → CSS files └ javascripts → Javascript files └ images → Image filesproject → sbt configuration files └ build.properties → Marker for sbt project └ plugins.sbt → sbt plugins & declaration for Play itselflogs → Standard logs folder └ application.log → Default log filetarget → Generated stufftest → source folder for unit or functional tests

myProject

Page 7: Play framework   productivity formula

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 -

Page 8: Play framework   productivity formula

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 !!!

Page 9: Play framework   productivity formula

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 LibraryWS.url(url).withHeaders("headerKey" -> "headerValue").get()

➔ request reading is also async➔ enables:

◆ WebSockets◆ Comet

Attention the database access most probably will not be async

Page 10: Play framework   productivity formula

Some async example

This can get even more fun

Page 11: Play framework   productivity formula

Play it’s production readyPlay is already being used by companies like:

Play is scalable

Instant deployment on

but you can found instruction for:CloudbeesCloud FoundryClever Cloud

Page 12: Play framework   productivity formula

Some other featuresDatabase evolutions

evolutions.use.locks=truedatabase locks are used to ensure that onlyone 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

Pluginsclasses that extend the Plugins trait

conf/play.plugins file

10000:my.example.FirstPlugin10001:my.example.SecondPlugin

<priority>:<classname>

def enabled : Booleandef onStart (): Unitdef onStop (): Unit

in

can overwrite the following methods

conf/evolutions/default/1.sqlconf/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 -> scalaintegration 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")}

Page 13: Play framework   productivity formula

What would you try

Java or Scalatry the samples folder