47
Play Framework and Activator Getting started with the Play Framework with Activator

Play Framework and Activator

Embed Size (px)

DESCRIPTION

A deep-dive into the core features of the Typesafe Activator and Play Framework.

Citation preview

Page 1: Play Framework and Activator

Play Framework and ActivatorGetting started with the Play Framework with Activator

Page 2: Play Framework and Activator

Topics, goals, context

2

• An introduction to Typesafe Activator

• An introduction to the core features of Play 2.x

• What is a Reactive application, and how do you build one with Play?

Page 3: Play Framework and Activator

Introduction to Typesafe Activator

Page 4: Play Framework and Activator

“Typesafe Activator is a browser-based or command-line tool that helps developers get started with the Typesafe Reactive Platform.”

Page 5: Play Framework and Activator

Getting started with the Typesafe Activator UI

5

• Download Typesafe Activator

• https://typesafe.com/platform/getstarted

• Optional (Mac)

• ~ $ rm -R .sbt

• ~ $ rm -R .ivy

• Unarchive and execute (Mac)

• $ ./activator ui

Page 6: Play Framework and Activator

Activator tutorials and seeds

6

Page 7: Play Framework and Activator

Activator Overview

7

• Learn — In depth tutorials

• Develop — Code, compile, test, run, inspect

• Deliver — Monitoring integration with AppDynamics and New Relic

Page 8: Play Framework and Activator

Code view

8

• Activator • Browse code

• Make small changes • IDE

• Generate IDEA or Eclipse project files

• Dig into the template in your favourite IDE

Page 9: Play Framework and Activator

Development monitoring

9

• Incoming requests • Controller • HTTP verb (GET, POST, etc)

• Response code

• Invocation time

Page 10: Play Framework and Activator

Inspect — Development monitoring

10

• Actor metrics • Throughput — messages/s

• Max time — high watermark

• Max size — mailbox

Page 11: Play Framework and Activator

Monitoring and support

11

• Application monitoring • Need production caliber monitoring?

• AppDynamics or New Relic integration • Support

• Ready to take your application to the next level?

• http://typesafe.com/how/subscription

Page 12: Play Framework and Activator

Contributing a template — tutorials vs seeds

12

• Seed • Boilerplate code as a starting point

• Tutorial • Teaching about a particular focused topic or integration

• Components

• Activator templates are just regular sbt projects with some additional components

• Metadata (activator.properties), license, sbt build file, tutorial (tutorial/index.html)

• Contribute!

• https://typesafe.com/activator/template/contribute

Page 13: Play Framework and Activator

The Typesafe Activator UI is a Play framework application. !

Peek behind the covers… !

https://github.com/typesafehub/activator/tree/master/ui

Page 14: Play Framework and Activator

Play 2.3 overview

14

• Stateless MVC framework with routing, a template engine, REST support, etc

• Dynamic class reloading

• Support for Java 8 and Scala 2.1x

• sbt-web to implement an asset pipeline

• Akka interoperability for highly concurrent web applications

• Built on Netty 3.9.x

Page 15: Play Framework and Activator

Play application overview

15

View

Controller

ModelJSON

Slick JPA WS

DB

Akka

Network

Page 16: Play Framework and Activator

Creating your first view

Page 17: Play Framework and Activator

17

Simplified HTTP request

1. mydomain.com/admin/settings

renders views.html.admin HTML

2. Browser fetches static assets served

from outside of Play

3. Ajax requests — Play serves JSON

via a RESTful API

HTML for views.html.admin(...)

Browser Play

CDN

HTTP GET (mydomain.com/admin/settings)

JS, CSS, images, etc

HTTP GET (mydomain.com/ws/some/services)

JSON

Page 18: Play Framework and Activator

Example template with AngularJS

18

• Scala template rendered by Twirl and returned by Play controller

• HTML inserted into ng-view by Angular controller after initial page render

@(customer: Customer)!!<head>...</head>!<body>! <div class="wrapper">! <header>…</header>! <h1>Welcome @customer.name!</h1>! <section id="body" ng-app="ngAdmin">! <div ng-view></div>! </section>! <footer>...</footer>! </div>!</body>!</html>

HeaderPlay handles navigation

Footer

load async || fail whale

load async || omit

AngularJS

Page 19: Play Framework and Activator

Creating your first routes and controllers

Page 20: Play Framework and Activator

routes

20

GET !/admin!! ! ! ! controllers.AdminController.index!GET ! /admin/login! ! ! controllers.AdminController.login!GET ! /admin/*any! ! ! controllers.AdminController.angularWildcard(any: String)!GET ! /ws/some/service! ! controllers.ServiceController.service

• Routes must be declared in order

• /admin and /admin/login are used to render Scala view templates

• /admin/*any will be intercepted by client-side routing in AngularJS

• Client-side routes may hit the server if the URI has been bookmarked

• Nothing special about web services aside from payload (JSON vs HTML)

Page 21: Play Framework and Activator

Sample controller action

21

/**! * Renders the admin template.! */! def index = Action.async {! implicit request =>! val account = loggedIn! Ok(views.html.admin()).withCookies(Cookie(“…”, …, httpOnly = false))! }

• Controllers should stay thin and delegate the real work

• Controllers actions should always be async • Controllers are stateless so context must be stored in cookies or cached

Page 22: Play Framework and Activator

Asynchronous vs synchronous processing times

22

Process 1

Process 2

Process 3

0 ms 425 ms

200 ms

75 ms

150 ms

Asynchronous - 200ms

Process 1 Process 2 Process 3

0 ms 425 ms

Synchronous - 425ms

• Staying async — and in the future — ensures that processing time is not bounded by IO

• Async processing is limited by only the longest running process

• Synchronous processing is limited by the combined processing times

• Stay async!

Page 23: Play Framework and Activator

Asset pipeline and sbt-web

Page 24: Play Framework and Activator

An intro to sbt-web

24

• sbt-web brings the notion of a highly configurable asset pipeline to build files

pipelineStages := Seq(rjs, digest, gzip)!

• The above will order the RequireJs optimizer (sbt-rjs), the digester (sbt-digest) and then compression (sbt-gzip)

• These tasks will execute in the order declared, one after the other

Page 25: Play Framework and Activator

Asset pipelines

25

• Example asset pipeline

• source file →

• step 1: linting →

• step 2: uglification/minification →

• step 3: fingerprinting →

• step 4: concatenation (optional)

Page 26: Play Framework and Activator

Asset pipelines

26

• Linting

• Inspect source code for suspicious language usage

• Uglification/minification

• Mangle and compress source files, e.g, remove whitespace, etc

• Fingerprinting

• Change the filename to reflect the contents of the file for cache busting

• Concatenation

• Combine multiple source files to reduce browser load times

Page 27: Play Framework and Activator

sbt-web and asset fingerprinting

27

• Asset fingerprinting makes the name of a file dependent on the contents of the file

• HTTP headers can be set to encourage caches to keep their own copy of the content

• When the content is updated, the fingerprint will change

• This will cause the remote clients to request a new copy of the content

• Known as cache busting

Page 28: Play Framework and Activator

Turning on asset fingerprinting

28

• Turning on asset fingerprinting only requires one additional route

GET /assets/*file! controllers.Assets.versioned(path="/public", file: Asset)

• Then request each asset as versioned

<link rel="stylesheet" href=“@routes.Assets.versioned('assets/images/example.png')">

• A digest file and new file will be created based on MD5

./target/web/digest/images/23dcc403b263f262692ac58437104acf-example.png!

./target/web/digest/images/example.png.md5

Page 29: Play Framework and Activator

sbt-web plugins

29

• sbt-coffeescript

• sbt-concat

• sbt-css-compress

• sbt-digest

• sbt-filter

• sbt-gzip

• sbt-handlebars

• sbt-html-minifier

• sbt-imagemin

• sbt-jshint

• sbt-jst

• sbt-less

• sbt-mocha

• sbt-purescript

• sbt-reactjs

• sbt-rjs

• sbt-stylus

• sbt-uglify

Page 30: Play Framework and Activator

Model-tier and data access

Page 31: Play Framework and Activator

Model-tier considerations

31

Think in verbs rather than nouns…

• save(model) • SRP — save is likely a simple function that does a single thing

• model.save() • Violates SRP — tougher to test

• Play makes it easy to implement your preferred solution to persistence

• CRUD, CQRS (Command Query Responsibility Segregation), etc

Page 32: Play Framework and Activator

Scala — Slick example

32

• Slick is a Functional Relational Mapping (FRM) library for Scala where you work with relational data in a type-safe and functional way

• Developers benefit from the type-safety and composability of FRM as well as being able to reuse the typical Scala collection APIs like filter, map, foreach, etc

• Can also use plain SQL for insertions, complex joins, etc

• http://typesafe.com/activator/template/hello-slick-2.1

// This code:!coffees.filter(_.price < 10.0).map(_.name)!!// Will produce a query equivalent to the following SQL:!select COF_NAME from COFFEES where PRICE < 10.0

Page 33: Play Framework and Activator

Scala — JSON Writes example

33

• Simply define a Writes in implicit scope before invoking toJson

implicit val locationWrites = new Writes[Location] {! def writes(location: Location) = Json.obj(! "lat" -> location.lat,! "long" -> location.long! )!}!!val json = Json.toJson(location)

Page 34: Play Framework and Activator

Scala — JSON Reads example

34

• Also elegantly handles Reads • Build in validate using standard

types (e.g, Double, Int, etc) or define your own validators

implicit val locationReads: Reads[Location] = (! (JsPath \ "lat").read[Double] and! (JsPath \ "long").read[Double]!)(Location.apply _)!!val json = { ... }!!val locationResult: JsResult[Location] = !! json.validate[Location]

Page 35: Play Framework and Activator

Futures, Actors, and WebSockets

Page 36: Play Framework and Activator

- Derek Wyatt, Akka Concurrency

“If you want to parallelize a very deterministic algorithm, futures are the way to go.”

Page 37: Play Framework and Activator

Futures

37

• Great for handling immutable state

• Intensive computations, reading from a database, pulling from web services, etc

• Composition — futures guarantee order when chained

• Parallelizing a deterministic algorithm

def index = Action.async {!! val futureInt = scala.concurrent.Future { intensiveComputation() }!! futureInt.map(i => Ok("Got result: " + i))!}

Page 38: Play Framework and Activator

- Derek Wyatt, Akka Concurrency

“Add behaviour to an algorithm by inserting actors into the message flow.”

Page 39: Play Framework and Activator

Actors

39

• Great for handling mutable state

• Easy for imperative developers to dive into quickly

• Don't guarantee order

• Easy to change behaviour by inserting new actors into the message flow

• Messages are directed to a specific actor, avoiding callback hell

package actors!!import akka.actor._!!object SomeActor {!! def props = Props(new GameActor)!}!!class SomeActor extends Actor {!! def receive = {!! ! case request: SomeRequest => {!! ! ! sender ! SomeResponse(...) !! ! }!! }!}!

Page 40: Play Framework and Activator

WebSockets

40

• Play provides two different built in mechanisms for handling WebSockets

• Actors — better for discreet messages

• Iteratees — better for streams

• Both of these mechanisms can be accessed using the builders provided on WebSocket

def websocketAction = WebSocket.acceptWithActor[JsValue, JsValue] { request => channel =>!! SomeActor.props(channel)!}!

Page 41: Play Framework and Activator

Testing

Page 42: Play Framework and Activator

Test framework comparison

42

• ScalaTest • Human readable output — in English

• FeatureSpec

• Matchers

• http://www.artima.com/docs-scalatest-2.0.M8/#org.scalatest.Matchers

• Great writeup by Gilt

• http://tech.gilt.com/post/62430610230/which-scala-testing-tools-should-you-use

Page 43: Play Framework and Activator

Test framework comparison

43

• Specs2 • Enabled by default in Play

• Good choice for international teams who gain less from English readability

• Both Specs2 and ScalaTest are fantastic!

Page 44: Play Framework and Activator

Coming soon to Play 2.4

Page 45: Play Framework and Activator

Play 2.4

45

• Built-in dependency injection support

• Experimental support for running Play on akka-http

• Experimental support for handling IO in Java and Scala using Reactive Streams

• Slick over anorm, JPA over ebean

• Pull anorm/ebean support out into separate modules in GitHub playframework repo

Page 46: Play Framework and Activator

Questions?

Page 47: Play Framework and Activator

©Typesafe 2014 – All Rights Reserved