play in practice

40
PLAY IN PRACTICE / Will Sargent @will_sargent

Upload: william-sargent

Post on 22-Nov-2014

13.909 views

Category:

Technology


0 download

DESCRIPTION

Slides from the SF Scala talk on "Play in Practice", 4/18/2013 Will Sargent

TRANSCRIPT

Page 1: Play in practice

PLAY IN PRACTICE / Will Sargent @will_sargent

Page 2: Play in practice

PREAMBLEThis is going to be a broad talk.

Page 3: Play in practice

USAGEThis talk does not attempt to be universal to all situations.

YMMV.

Page 4: Play in practice

WHAT IS PLAY?Play is a web application framework.

Page 5: Play in practice

THESIS STATEMENTPlay is awesome.

Page 6: Play in practice

WHY PLAY IS AWESOME?Because Play is Simple.

Page 7: Play in practice

HERE'S WHAT PLAY DOES:Takes in an HTTP request.Returns (or streams) a response.

Page 8: Play in practice

HERE'S WHAT PLAY DOESN'T DO:It doesn't tie an HTTP request to a thread.It doesn't tie an HTTP session to memory.It doesn't assume you want convenient but unsafepractices.It doesn't mandate a particular object relationalframework.It doesn't mandate a particular template library.It doesn't mandate a particular routing format.

Page 9: Play in practice

HERE'S WHAT PLAY PROVIDES AS OPTIONS:"Always-on" Build SystemHTTP APITemplatesForm HandlingJSON support

Page 10: Play in practice

BUILD SYSTEMModified SBT, recompiles pages on the fly in developmentmode.Type "play idea" or "play eclipse" to generate the files foryour IDE.

Page 11: Play in practice

FRONT CONTROLLERRouting API (with LangPathBindable andQueryStringBindable)Action: asynchronous and stateless by default.Immutable HTTP: cookies, request, response, headers, etc.Backed by Akka and Netty.

Page 12: Play in practice

PRESENTATIONCompiled template language (Twirl, Scaml, Jade).Built-in helpers for rendering forms.Support for Twitter Bootstrap, LESS, jQuery, etc.

Page 13: Play in practice

JSONFormatting to JSONParsing of JSON objectsJsPath, automatic validation, read and write combinators

Page 14: Play in practice

SO, WHY DOES THIS MATTER?

Page 15: Play in practice

THE BUSINESS REQUESTMake a website!

Page 16: Play in practice

MAKE TWO WEBSITES!ProductAdmin

Page 17: Play in practice

MAKE MORE WEBSITES!ProductAdminCustomer ServiceBusiness AnalyticsBusiness ContentJobs Queue

Page 18: Play in practice

THE PROBLEMIn a complex web application, many different front ends need

to look at the same data, from different angles.

Touching the database directly is dangerous and messy.

Page 19: Play in practice

THE SOLUTIONIn complex applications, use loosely coupled, stateless,

composable services.

Page 20: Play in practice

HOW?Create a Play HTTP front end, backed by Akka.Create a business domain services, backed by Akka.Use Akka to pass messages between Play and the domainservices.Present information using query services.

Page 21: Play in practice

ALAN KAY ON OOP“ I thought of objects being like biological cells

and/or individual computers on a network,only able to communicate with messages (so

messaging came at the very beginning -- ittook a while to see how to do messaging in aprogramming language efficiently enough to

be useful). ”

Page 22: Play in practice

COMMAND / QUERY RESPONSIBILITYSEGREGATION (CQRS)

Command: a message intending a change of state.Event: a message indicating that state has changed.Fault: a message indicating failure to execute a command.

Page 23: Play in practice

CQRS MAPPED ONTO PLAYProcessing Commands using POSTQuerying for Data with GETBroadcasting Events with Streaming

Page 24: Play in practice

PROCESSING COMMANDSValidate all input.

where possible.Be very careful when handling passwords and credit cardnumbers.

Use value classes

Page 25: Play in practice

COMMANDSdef sendCommand(command : Command) : Future[Either[Fault,Event]]

Page 26: Play in practice

CQRS

Page 27: Play in practice

COMMANDtrait Command extends Product

sealed abstract class AuthenticationCommand extends Command

case class AuthenticateWithPasswordCommand(email:Email, password:String, rememberMe:Boolean) extends AuthenticationCommand { override def toString = "AuthenticateWithPasswordCommand(" + email + "," + rememberMe + ")"}

Page 28: Play in practice

EVENTcase class UserAuthenticatedEvent(userId: UserID, series: Option[Long] = None, token: Option[Long] = None) extends AuthenticationEvent

Page 29: Play in practice

FAULTtrait AuthenticationFault

case class InvalidSessionCookieFault() extends AuthenticationFault

Page 30: Play in practice

QUERYcase class UserInfo(id: UUID, email: Email, fullName: String)

class UserInfoService {def lookup(uuid: UUID)(implicit c:Credentials): Option[UserInfo]def findByName(name: String)(implicit c:Credentials) : TraversableOnce[UserInfo}

Page 31: Play in practice

QUERY PRACTICES:Objects should be immutableReturn ranges or streams over unbounded lists.Don't expose repository logic (i.e. HQL, CQL, etc)Making a good query builder is hard; avoid yak shaving.

Page 32: Play in practice

CONTEXT AND AUTHENTICATIONUse or to set up aWrappedRequest context.Pass the request context around implicitly in everytemplate.The request context will contain all the state you need (i.e.Credentials).Make helpers take the context as an implicit as needed.Sidenote: helpers are great for keeping logic out oftemplates.

play2-rememberme SecureSocial

Page 33: Play in practice

EXAMPLE TEMPLATE@(u: UserInfo)(implicit ctx: Context)

@layout(title = "User Page") { @ctx.me.map { u => <p> This is your user page. </p> }

<p> User page of @{u.fullName}. </p>}

Page 34: Play in practice

STREAMINGYou send an event.Event goes through an Iteratee.Iteratee broadcasts event using Socket and Hub model.Play uses Server Sent Events to stream JSON to clientsJavascript picks up that JSON from SSE, handles display.

is the best reference.Sidenote: also check out lila

vert.x

Page 35: Play in practice

EVERYTHING ELSELoggingMetricsTesting

Page 36: Play in practice

LOGGINGPlay's internal logger isn't the greatest.Fortunately, it's not hardcoded and you can ignore it.Make your own wrapper over SF4LJ & Logback (orgrizzled, or typesafe logging).

Page 37: Play in practice

METRICS has a Scala option.

Map it through Global's onRequest method.Metrics

Page 38: Play in practice

TESTINGUnit testing a stateless app is very easy.Swapping out services with mocks/stubs may be easierwith DI (I use Subcut).Functional and integration testing with FakeRequest andFluentlenium almost painless.

Page 39: Play in practice

LOAD TESTINGUse jconsole and .Don't know how useful Typesafe Console is.

Apache JMeter

Page 40: Play in practice

QUESTIONS?There's an award!