play in practice

Post on 22-Nov-2014

13.909 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

PLAY IN PRACTICE / Will Sargent @will_sargent

PREAMBLEThis is going to be a broad talk.

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

YMMV.

WHAT IS PLAY?Play is a web application framework.

THESIS STATEMENTPlay is awesome.

WHY PLAY IS AWESOME?Because Play is Simple.

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

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.

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

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

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

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

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

SO, WHY DOES THIS MATTER?

THE BUSINESS REQUESTMake a website!

MAKE TWO WEBSITES!ProductAdmin

MAKE MORE WEBSITES!ProductAdminCustomer ServiceBusiness AnalyticsBusiness ContentJobs Queue

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.

THE SOLUTIONIn complex applications, use loosely coupled, stateless,

composable services.

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.

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). ”

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.

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

PROCESSING COMMANDSValidate all input.

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

Use value classes

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

CQRS

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

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

FAULTtrait AuthenticationFault

case class InvalidSessionCookieFault() extends AuthenticationFault

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}

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.

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

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

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

EVERYTHING ELSELoggingMetricsTesting

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

METRICS has a Scala option.

Map it through Global's onRequest method.Metrics

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.

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

Apache JMeter

QUESTIONS?There's an award!

top related