Play framework productivity formula

Post on 01-Nov-2014

1415 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

Play framework

Transcript

Play Framework (Scala)

Productivity Formula by Sorin Chiprian

What is Play?

Play is a cool frameworkEasy to learn

Play supports both Scala & Java

What do I like mostBest 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.confenvironment="development"

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

● production.confinclude "application.conf"

environment="production"

db.default.url = ${?MYSQL_URL}

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.

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

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

Some async example

This can get even more fun

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

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")}

What would you try

Java or Scalatry the samples folder

top related