SlideShare a Scribd company logo
Play Framework 
Lessons Learned 
@PeterHilton 
http://hilton.org.uk/
Lessons learned 
1. Coolness 
2. Architecture 
3. Writing code 
4. Dev/prod environments 
5. Reducing project risk 
@PeterHilton • 2
Lesson 1: 
Play is cool
‘Anyone who says 
“and using this tool I can 
remove the programmers” 
just became the programmer’ 
! 
Allan Kelly - @allankellynet 
@PeterHilton • 4
Play Framework 
Action-based MVC web framework 
for applications in Java or Scala. 
! 
Full-stack framework with a simple, 
flexible and powerful HTTP API and a 
high-performance scalable architecture. 
@PeterHilton • 5
package controllers 
! 
import play.api.mvc.{Action, Controller} 
import models.Product 
! 
// Play web application controller. 
object Products extends Controller { 
! 
// Action method -­‐ show a list of products. 
def list = Action { 
val products = Product.findAll 
Ok(views.html.products.list(products)) 
} 
}
/** Formats a Product instance as JSON. */ 
implicit object ProductWrites extends Writes[Product] { 
def writes(product: Product) = Json.obj( 
"name" -­‐> Json.toJson(product.name), 
"description" -­‐> Json.toJson(product.description)) 
} 
! 
/** Render a list of products in JSON format. */ 
def listJson = Action { 
// Automatically sets Content-­‐type: application/json 
Ok(Json.toJson(Product.findAll)) 
}
# HTTP routes configuration. 
! 
GET /products controllers.Products.list 
GET /products.json controllers.Products.listJson 
HTTP 
method 
URL path controller action mapping
Play Framework 
Designed by web developers 
for web developers 
! 
High-productivity web development 
! 
Play is fun 
@PeterHilton • 9
Template syntax starts with @ 
Template parameter declaration 
@(products: List[Product]) 
! 
! 
@if(products.isEmpty) { 
! 
<h1>No products</h1> 
! 
} 
No delimiter for the end of a 
template syntax section
@(products: List[Product]) 
! 
! 
@if(products.isEmpty) { 
! 
<h1>No products</h1> 
! 
} else { 
! 
<h1>@products.size products</h1> 
! 
} Output the value of an expression
@(products: List[Product]) 
! 
@if(!products.isEmpty) { 
! 
<table> 
@for((product, index) <-­‐ products.zipWithIndex) { 
<tr class='@(if (index % 2 == 0) "even" else "odd" )'> 
<td>@product.name</td> 
<td>@product.price</td> 
</tr> 
} 
</table> 
}
@(! 
products: List[Product]) 
! 
! 
@if(!products.isEmpty) { 
! 
! 
<table> 
! 
@for((product, index) <-­‐ products.zipWithIndex) { 
<tr class='@(if (index % 2 == 0) "even" else "odd" )'> 
<td>@product.name</td> 
<td>@product.price</td> 
</tr> 
} 
</table> 
} 
XML inside an 
HTML attribute 
would be a mess
Code reloading 
1. Change code (Java, Scala, HTML, etc) 
2. ⌘R 
! 
Code reloading is essential for: 
immediate feedback 
fast development cycle 
maintaining developer focus… 
@PeterHilton • 13
Play framework: lessons learned
Play framework: lessons learned
Parse error: syntax error, unexpected T_VARIABLE 
in /usr/local/www/htdocs/index.php on line 3
Play framework: lessons learned
Error messages 
Error messages must be 
immediate, 
in the right place and 
include context 
@PeterHilton • 17
Developer Experience (DX) 
Developers are people too 
DX is UX for developers 
Good DX = happy + productive developers 
! 
Code reloading and good error messages 
are the most important factors for good DX 
@PeterHilton • 18
More cool front-end features 
Manage dependencies with web jars 
LESS compilation 
CoffeeScript compilation 
JSHint JavaScript code checking 
RequireJS integration 
Built-in ETag, GZip and Cache-Control 
@PeterHilton • 19
Summary 
Code reloading during development 
Useful error pages 
Clean API for direct HTTP programming 
(doesn’t break the web browser) 
Modern front-end development 
(plays with HTML5 instead of fighting it) 
High-performance HTTP server 
@PeterHilton • 20
Lesson 2: 
Architecture
‘All problems in computer science can be 
solved by another level of indirection, 
except of course for the problem of too 
many indirections.’ 
! 
David Wheeler 
@PeterHilton • 22
Direct HTTP programming 
HTTP and the web matter 
We don’t need to hide HTTP 
! 
We don’t need another abstraction layer 
(or any other kind of indirection) 
! 
Play has a well-designed flatter HTTP API 
(Play doesn’t use the Servlet API) @PeterHilton • 23
Play framework: lessons learned
Stateless architecture 
No state in the application’s web tier 
e.g. Java Servlet API’s ‘HTTP session’ 
State belongs in other tiers: 
HTTP client, server cache or database 
Web app behaviour defined by URLs 
(except for identifying the logged-in user) 
@PeterHilton • 25
Stateless architecture benefits 
Simplified development and testing 
(a URL is all you need for reproducibility) 
Matches stateless web architecture 
(HTTP is stateless by design) 
Avoids synchronising state between layers 
(‘sync’ should ring tech design alarm bells) 
Cloud deployment & horizontal scalability 
e.g. on Heroku or Cloudbees 
@PeterHilton • 26
The web browser is your friend 
! 
Friends don’t let friends 
break standard HTTP features 
Don’t break the Back button 
Keep your URLs clean 
@PeterHilton • 27
h t t p : / / a p p . e x a m p l e . c o m / W a r R o o t 
W e b D i r e c t o r y 1 / S e r v l e t s O n A P l a n e ? 
s e s s i o n I d = x 8 1 n j 3 8 a v n g j L O L a n 4 w 
q & a c t i o n = N e x t P a g e & H o n e y B a d g e r 
C a r e s = f a l s e & e n t i t y I d = 1 2 9 9 1 2 7 4 3 
& p r o c e s s I d = U n l a d e n S w a l l o w C a l c & 
r o l e = p e o n & d a t e = 7 % 2 F 1 0 % 2 F 2 0 1 4 
& f l a g S e t t i n g s = 0 1 0 1 0 1 1 1 0 0 1 0 1 1 & 
r e d i r e c t = % 2 F v i d e o s % 2 F r i c k r o l l . a v i
URL-centric design 
Clean URLs are stable URLs - your 
application’s public API (and part of the UI) 
http://example.com/products 
http://example.com/product/42 
Design the URL scheme before coding. 
Configure application URLs in one file. 
Read it, bookmark it, mail it, tweet it. 
@PeterHilton • 29
# HTTP routes configuration file 
! 
GET / controllers.Application.index() 
! 
GET /products controllers.Products.list() 
POST /products controllers.Products.add(p: Product) 
GET /product/:id controllers.Products.details(id: Long) 
DELETE /product/:id controllers.Products.delete(id: Long) 
! 
GET /products.json controllers.Products.listJSON() 
GET /product/:id.json controllers.Products.detailsJSON(id:Long)
User-interface architecture 
Think carefully about UI layer architecture 
Embrace HTML5 technologies 
Consider modern approaches: 
CoffeeScript instead of JavaScript 
LESS instead of CSS 
Twitter Bootstrap for consistent HTML. 
@PeterHilton • 31
What’s worse than spaghetti code?
Lasagne architecture! 
UI, web tier, services, business logic, model, database, etc 
plasticrevolver / CC BY-SA 2.0
Play framework: lessons learned
Play framework: lessons learned
view 
URL routing 
controllers templates 
model 
database mapping 
HTTP 
queries 
renders 
presents 
calls
Architecture summary 
A stateful web tier is not a cool thing 
Embrace HTTP-centric web architecture 
Beware of lasagne architecture 
Unlearn complexity and n-tier habits 
Combine multiple design perspectives 
UI-centric vs model-centric vs URL-centric 
Use cloud-ready architecture 
Leverage cloud tooling for running locally 
@PeterHilton • 37
Lesson 3: 
Writing code
Optimising for time may cost you… 
CPU time vs programmer vs maintainer efficiency
Writing Scala code 
Don’t worry about Scala style to start with 
(your code style will evolve anyway) 
Start with the syntax 
It takes a year to discover idiomatic style 
@PeterHilton • 40
Writing code 
Spend time on code review or 
pair programming 
Don’t to be clever 
Aim for consistency 
Optimise code for maintainability 
@PeterHilton • 41
Scala coding rules of thumb 
Immutability is your friend 
Learn to use functional style in methods 
… but don’t go overboard 
Humans need more info than the compiler 
… so add more variable names and types 
Use the REPL to try things out 
@PeterHilton • 42
Scala coding recommendations 
Study the (immutable) collections API 
(ignore mutable collections) 
! 
Put logic in pure functions and test those 
def calculateRiskScore 
(factors: List[Factor]): Int 
@PeterHilton • 43
Scala coding recommendations 
Split large classes into traits 
! 
Sometimes a Customer is just a 
NamedOrganisation 
! 
Using more specific traits improves 
maintainability and compilation speed 
@PeterHilton • 44
Play application code 
Keep controllers and templates lightweight 
Single-use view case classes: 
@PeterHilton • 45 
! 
case class ProductListView( 
id: Int, 
name: String, 
available: Boolean)
Play application code 
Learn how to write custom components 
that work as if they were built-in: 
template formatters 
database column types 
body parsers - custom request body types 
writeables - custom HTTP response types 
@PeterHilton • 46
// Code example: custom Play framework template formatters 
! 
package templates 
! 
object Formatters { 
! 
// e.g. @updated.format in a template outputs ‘2013-­‐10-­‐25’ 
implicit class RichLocalDate(date: org.joda.time.LocalDate) { 
def format(): String = format("yyyy-­‐MM-­‐dd") 
def format(pattern: String) = date.toString(pattern) 
} 
! 
// e.g. @price.format in a tempate outputs ‘EUR 2.99’ 
implicit class RichMoney(m: org.joda.money.Money) { 
import play.api.templates.Html 
def format = 
Html("${m.getCurrencyUnit.getCode}&nbsp;${m.getAmount}") 
}
Third-party libraries 
There is no Father Christmas Hibernate. 
Seriously. 
ORM isn’t a Scala thing 
Learn the alternatives 
Slick is good but not particularly easy 
NoSQL persistence may be easier to use 
MongoDB, Neo4J, ElasticSearch, etc 
@PeterHilton • 48
// Code example: Scala Slick database access 
! 
// Nice: select * from LICENSE where id=? 
val query = Query(Licenses).filter(_.id === id)
// Code example: Scala Slick database access 
! 
// Nice: select * from LICENSE where id=? 
val query = Query(Licenses).filter(_.id === id) 
! 
! 
! 
// Nasty: select b.NUMBER, b.DATE, p.NAME, o.NAME from BOOKING b 
// inner join ACCOUNT a on (a.ID=b.FROM_ID) 
// left outer join PERSON p on (p.ID=a.PERSON_ID) 
// left outer join ORGANISATION o on (o.ID=a.ORGANISATION_ID) 
val query = for { 
entry ← BookingEntries 
((fromAccount, fromPerson), fromOrganisation) ← Accounts leftJoin 
People on (_.personId === _.id) leftJoin 
Organisations on (_._1.organisationId === _.id) 
if fromAccount.id === entry.fromId 
} yield ( 
entry.bookingNumber, entry.bookingDate, 
fromPerson.name.?, fromOrganisation.name.?)
Lesson 4: 
Dev/prod 
environments
Deployment infrastructure 
Move on from application servers 
Deploy to production before coding 
Cloud deployment for test/prod is easy 
Cloudbees, Heroku 
Databases are commodity cloud resources 
especially MySQL - Amazon RDS 
@PeterHilton • 51
Development environment set-up 
example 
1. Install dependencies: 
Java JDK 1.7, git, Play 2.1.3, MySQL 5.6 
2. Clone GitHub repository 
https://github.com/HappyMelly/teller 
3. Create MySQL database and user 
! 
4. Start application 
Play Evolutions SQL script initialises DB 
@PeterHilton • 52
CloudBees deployment process 
example 
1. Source code in GitHub repository 
2. Develop code in feature branches 
3. Merge commits to master after review 
4. Automatic test deploy on push to GitHub 
5. Smoke test on test server with prod data 
6. Use Jenkins to promote the build to prod 
@PeterHilton • 53
Deployment - dev environment 
Set-up your development environment as if 
you were doing an open-source project: 
Minimal steps to get started on a fresh 
machine, 
Idiot-proof instructions 
@PeterHilton • 54
Deployment - prod environment 
Set-up your production environment as if 
you were deploying to the cloud: 
Match the development environment, 
Support continuous deployment, 
Automate deployment from the version 
control system 
@PeterHilton • 55
http://12factor.net
12 factors for cloud deployment 
@PeterHilton • 57 
1. Codebase 
2. Dependencies 
3. Configuration 
4. Backing services 
5. Build/release/run 
6. Processes 
7. Port binding 
8. Concurrency 
9. Disposability 
10. Dev/prod parity 
11. Logs 
12. Admin processes 
http://12factor.net
Lesson 5: 
Project risk
Doing it the easy way 
Become Scala experts: 
Type system, compiler errors, OO vs FP 
! 
Become Play experts: 
Try out most of Play’s features 
Learn how Play works internally 
Build ten experimental applications 
@PeterHilton • 59
Doing it the hard way 
The same as the easy way, but 
without a year before the first real project 
! 
Many new things at the same time is hard: 
uncertainty - especially unknown duration, 
risk - rework and operational issues 
@PeterHilton • 60
Starting a project 
Enable high-productivity: 
Have very fast laptops - SSD, lots of RAM 
Match the team to the architecture: 
Keep both simple - at least to start with, 
Decide how to work with front-end devs, 
Have a Scala expert available 
Do experiments, or get help, to start faster 
@PeterHilton • 61
M A N N I N G 
Covers Play 2 
Peter Hilton 
Erik Bakker 
Francisco Canedo 
FOREWORD BY James Ward 
Play for Scala 
(Manning) 
! 
Peter Hilton 
Erik Bakker 
Francisco Canedo 
! 
http://bit.ly/playscala2p
Play framework: lessons learned
Reducing project risk - summary 
Community events - talking to other teams 
e.g. London Scala Users’ Group 
Read the book - don’t learn the hard way 
! 
Attend the training course to learn faster 
Hire an expert to reduce project risk 
@PeterHilton • 64
@PeterHilton 
http://hilton.org.uk/

More Related Content

PDF
Process-oriented reactive service architecture
PDF
HTTP demystified for web developers
PDF
Play framework 2 : Peter Hilton
PDF
Play Framework: The Basics
PDF
Introduction in the play framework
PPTX
API Documentation Workshop tcworld India 2015
PDF
Using Play Framework 2 in production
PPTX
Publishing API documentation -- Workshop
Process-oriented reactive service architecture
HTTP demystified for web developers
Play framework 2 : Peter Hilton
Play Framework: The Basics
Introduction in the play framework
API Documentation Workshop tcworld India 2015
Using Play Framework 2 in production
Publishing API documentation -- Workshop

What's hot (20)

PPTX
Silicon Valley Code Camp 2011: Play! as you REST
PPTX
Documenting REST APIs
PPTX
API Documentation -- Presentation to East Bay STC Chapter
PPTX
API workshop: Deep dive into Java
KEY
Features, Exportables & You
PPTX
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...
PPTX
Publishing API documentation -- Presentation
PDF
Engage 2015 - 10 Mistakes You and Every XPages Developer Make. Yes, I said YOU!
PPTX
Pantheon basics
PDF
Testing Code.org's Interactive CS Curriculum
PPTX
API workshop: Introduction to APIs (TC Camp)
PDF
Spring rest-doc-2015-11
PDF
01 spring-intro
PPTX
API Workshop: Deep dive into code samples
PPTX
Publishing strategies for API documentation
PDF
PDF
Selenium RC: Automated Testing of Modern Web Applications
PPTX
Play! Framework for JavaEE Developers
PDF
Play Framework 2.5
Silicon Valley Code Camp 2011: Play! as you REST
Documenting REST APIs
API Documentation -- Presentation to East Bay STC Chapter
API workshop: Deep dive into Java
Features, Exportables & You
Survival Strategies for API Documentation: Presentation to Southwestern Ontar...
Publishing API documentation -- Presentation
Engage 2015 - 10 Mistakes You and Every XPages Developer Make. Yes, I said YOU!
Pantheon basics
Testing Code.org's Interactive CS Curriculum
API workshop: Introduction to APIs (TC Camp)
Spring rest-doc-2015-11
01 spring-intro
API Workshop: Deep dive into code samples
Publishing strategies for API documentation
Selenium RC: Automated Testing of Modern Web Applications
Play! Framework for JavaEE Developers
Play Framework 2.5
Ad

Viewers also liked (20)

PDF
Play framework
PDF
Play Framework workshop: full stack java web app
PDF
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
PDF
The Play Framework at LinkedIn
PDF
TCE introduction (scalability with Scala and Akka)
PDF
Play Framework and Activator
PPTX
Designing a play framework application
PDF
Lessons Learned - Spielend einfach!
PDF
DWX2016: Der perfekte Mitarbeiter - vom T-Shape zum Team-Shape
PPTX
Presentación capmasao2013
KEY
Enterprise Java Web Application Frameworks Sample Stack Implementation
PDF
OOP2017: Scrum statt Murcs - Agile Software-Entwicklung
PDF
Web application development using Play Framework (with Java)
PDF
Scala, SBT & Play! for Rapid Application Development
PDF
Play Framework: async I/O with Java and Scala
PDF
AWS Lambda and Serverless framework: lessons learned while building a serverl...
PDF
Asynchronous, Event-driven Network Application Development with Netty
PPTX
Why Play Framework is fast
PDF
Einfach gute Retrospektiven moderieren
PDF
Node.js vs Play Framework
Play framework
Play Framework workshop: full stack java web app
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
The Play Framework at LinkedIn
TCE introduction (scalability with Scala and Akka)
Play Framework and Activator
Designing a play framework application
Lessons Learned - Spielend einfach!
DWX2016: Der perfekte Mitarbeiter - vom T-Shape zum Team-Shape
Presentación capmasao2013
Enterprise Java Web Application Frameworks Sample Stack Implementation
OOP2017: Scrum statt Murcs - Agile Software-Entwicklung
Web application development using Play Framework (with Java)
Scala, SBT & Play! for Rapid Application Development
Play Framework: async I/O with Java and Scala
AWS Lambda and Serverless framework: lessons learned while building a serverl...
Asynchronous, Event-driven Network Application Development with Netty
Why Play Framework is fast
Einfach gute Retrospektiven moderieren
Node.js vs Play Framework
Ad

Similar to Play framework: lessons learned (20)

PDF
Add-On Development: EE Expects that Every Developer will do his Duty
PDF
presentation
PDF
django_introduction20141030
PPTX
Training HTML5 CSS3 Ilkom IPB
PDF
Introduction to interactive data visualisation using R Shiny
PPT
Codeigniter
PDF
presentation
PDF
Add-On Development: EE Expects that Every Developer will do his Duty
PPTX
Lecture 2 HTML part 1.pptxLecture 10 CSS part 2.pptxvvvvvvvvvvvvvv
PPTX
The current status of html5 technology and standard
PPTX
Essential html tweaks for accessible themes
PDF
GDG Addis - An Introduction to Django and App Engine
PPTX
HTML5 and Search Engine Optimization (SEO)
PPTX
Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...
PPTX
C#Portfolio
PPT
PDF
Html 5 in a big nutshell
PDF
Web components - The Future is Here
PPTX
MVC & SQL_In_1_Hour
Add-On Development: EE Expects that Every Developer will do his Duty
presentation
django_introduction20141030
Training HTML5 CSS3 Ilkom IPB
Introduction to interactive data visualisation using R Shiny
Codeigniter
presentation
Add-On Development: EE Expects that Every Developer will do his Duty
Lecture 2 HTML part 1.pptxLecture 10 CSS part 2.pptxvvvvvvvvvvvvvv
The current status of html5 technology and standard
Essential html tweaks for accessible themes
GDG Addis - An Introduction to Django and App Engine
HTML5 and Search Engine Optimization (SEO)
Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...
C#Portfolio
Html 5 in a big nutshell
Web components - The Future is Here
MVC & SQL_In_1_Hour

More from Peter Hilton (9)

PDF
Naming guidelines for professional programmers
PDF
Beautiful code
PDF
E-Prime: English for scientific writing
PDF
How to write maintainable code
PDF
Documentation avoidance for developers
PDF
Meeting-avoidance for self-managing developers
PDF
How to write good comments
PDF
Scaling business app development with Play and Scala
PDF
How to name things: the hardest problem in programming
Naming guidelines for professional programmers
Beautiful code
E-Prime: English for scientific writing
How to write maintainable code
Documentation avoidance for developers
Meeting-avoidance for self-managing developers
How to write good comments
Scaling business app development with Play and Scala
How to name things: the hardest problem in programming

Recently uploaded (20)

PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PPTX
Reimagine Home Health with the Power of Agentic AI​
PPTX
Advanced SystemCare Ultimate Crack + Portable (2025)
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Autodesk AutoCAD Crack Free Download 2025
PDF
Complete Guide to Website Development in Malaysia for SMEs
PDF
17 Powerful Integrations Your Next-Gen MLM Software Needs
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Nekopoi APK 2025 free lastest update
PPTX
Patient Appointment Booking in Odoo with online payment
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
Salesforce Agentforce AI Implementation.pdf
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
iTop VPN 6.5.0 Crack + License Key 2025 (Premium Version)
PPTX
CHAPTER 2 - PM Management and IT Context
PPTX
assetexplorer- product-overview - presentation
PDF
How to Make Money in the Metaverse_ Top Strategies for Beginners.pdf
PPTX
Why Generative AI is the Future of Content, Code & Creativity?
PPTX
Computer Software and OS of computer science of grade 11.pptx
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
wealthsignaloriginal-com-DS-text-... (1).pdf
Reimagine Home Health with the Power of Agentic AI​
Advanced SystemCare Ultimate Crack + Portable (2025)
Odoo Companies in India – Driving Business Transformation.pdf
Autodesk AutoCAD Crack Free Download 2025
Complete Guide to Website Development in Malaysia for SMEs
17 Powerful Integrations Your Next-Gen MLM Software Needs
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Nekopoi APK 2025 free lastest update
Patient Appointment Booking in Odoo with online payment
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Salesforce Agentforce AI Implementation.pdf
Design an Analysis of Algorithms II-SECS-1021-03
iTop VPN 6.5.0 Crack + License Key 2025 (Premium Version)
CHAPTER 2 - PM Management and IT Context
assetexplorer- product-overview - presentation
How to Make Money in the Metaverse_ Top Strategies for Beginners.pdf
Why Generative AI is the Future of Content, Code & Creativity?
Computer Software and OS of computer science of grade 11.pptx

Play framework: lessons learned

  • 1. Play Framework Lessons Learned @PeterHilton http://hilton.org.uk/
  • 2. Lessons learned 1. Coolness 2. Architecture 3. Writing code 4. Dev/prod environments 5. Reducing project risk @PeterHilton • 2
  • 3. Lesson 1: Play is cool
  • 4. ‘Anyone who says “and using this tool I can remove the programmers” just became the programmer’ ! Allan Kelly - @allankellynet @PeterHilton • 4
  • 5. Play Framework Action-based MVC web framework for applications in Java or Scala. ! Full-stack framework with a simple, flexible and powerful HTTP API and a high-performance scalable architecture. @PeterHilton • 5
  • 6. package controllers ! import play.api.mvc.{Action, Controller} import models.Product ! // Play web application controller. object Products extends Controller { ! // Action method -­‐ show a list of products. def list = Action { val products = Product.findAll Ok(views.html.products.list(products)) } }
  • 7. /** Formats a Product instance as JSON. */ implicit object ProductWrites extends Writes[Product] { def writes(product: Product) = Json.obj( "name" -­‐> Json.toJson(product.name), "description" -­‐> Json.toJson(product.description)) } ! /** Render a list of products in JSON format. */ def listJson = Action { // Automatically sets Content-­‐type: application/json Ok(Json.toJson(Product.findAll)) }
  • 8. # HTTP routes configuration. ! GET /products controllers.Products.list GET /products.json controllers.Products.listJson HTTP method URL path controller action mapping
  • 9. Play Framework Designed by web developers for web developers ! High-productivity web development ! Play is fun @PeterHilton • 9
  • 10. Template syntax starts with @ Template parameter declaration @(products: List[Product]) ! ! @if(products.isEmpty) { ! <h1>No products</h1> ! } No delimiter for the end of a template syntax section
  • 11. @(products: List[Product]) ! ! @if(products.isEmpty) { ! <h1>No products</h1> ! } else { ! <h1>@products.size products</h1> ! } Output the value of an expression
  • 12. @(products: List[Product]) ! @if(!products.isEmpty) { ! <table> @for((product, index) <-­‐ products.zipWithIndex) { <tr class='@(if (index % 2 == 0) "even" else "odd" )'> <td>@product.name</td> <td>@product.price</td> </tr> } </table> }
  • 13. @(! products: List[Product]) ! ! @if(!products.isEmpty) { ! ! <table> ! @for((product, index) <-­‐ products.zipWithIndex) { <tr class='@(if (index % 2 == 0) "even" else "odd" )'> <td>@product.name</td> <td>@product.price</td> </tr> } </table> } XML inside an HTML attribute would be a mess
  • 14. Code reloading 1. Change code (Java, Scala, HTML, etc) 2. ⌘R ! Code reloading is essential for: immediate feedback fast development cycle maintaining developer focus… @PeterHilton • 13
  • 17. Parse error: syntax error, unexpected T_VARIABLE in /usr/local/www/htdocs/index.php on line 3
  • 19. Error messages Error messages must be immediate, in the right place and include context @PeterHilton • 17
  • 20. Developer Experience (DX) Developers are people too DX is UX for developers Good DX = happy + productive developers ! Code reloading and good error messages are the most important factors for good DX @PeterHilton • 18
  • 21. More cool front-end features Manage dependencies with web jars LESS compilation CoffeeScript compilation JSHint JavaScript code checking RequireJS integration Built-in ETag, GZip and Cache-Control @PeterHilton • 19
  • 22. Summary Code reloading during development Useful error pages Clean API for direct HTTP programming (doesn’t break the web browser) Modern front-end development (plays with HTML5 instead of fighting it) High-performance HTTP server @PeterHilton • 20
  • 24. ‘All problems in computer science can be solved by another level of indirection, except of course for the problem of too many indirections.’ ! David Wheeler @PeterHilton • 22
  • 25. Direct HTTP programming HTTP and the web matter We don’t need to hide HTTP ! We don’t need another abstraction layer (or any other kind of indirection) ! Play has a well-designed flatter HTTP API (Play doesn’t use the Servlet API) @PeterHilton • 23
  • 27. Stateless architecture No state in the application’s web tier e.g. Java Servlet API’s ‘HTTP session’ State belongs in other tiers: HTTP client, server cache or database Web app behaviour defined by URLs (except for identifying the logged-in user) @PeterHilton • 25
  • 28. Stateless architecture benefits Simplified development and testing (a URL is all you need for reproducibility) Matches stateless web architecture (HTTP is stateless by design) Avoids synchronising state between layers (‘sync’ should ring tech design alarm bells) Cloud deployment & horizontal scalability e.g. on Heroku or Cloudbees @PeterHilton • 26
  • 29. The web browser is your friend ! Friends don’t let friends break standard HTTP features Don’t break the Back button Keep your URLs clean @PeterHilton • 27
  • 30. h t t p : / / a p p . e x a m p l e . c o m / W a r R o o t W e b D i r e c t o r y 1 / S e r v l e t s O n A P l a n e ? s e s s i o n I d = x 8 1 n j 3 8 a v n g j L O L a n 4 w q & a c t i o n = N e x t P a g e & H o n e y B a d g e r C a r e s = f a l s e & e n t i t y I d = 1 2 9 9 1 2 7 4 3 & p r o c e s s I d = U n l a d e n S w a l l o w C a l c & r o l e = p e o n & d a t e = 7 % 2 F 1 0 % 2 F 2 0 1 4 & f l a g S e t t i n g s = 0 1 0 1 0 1 1 1 0 0 1 0 1 1 & r e d i r e c t = % 2 F v i d e o s % 2 F r i c k r o l l . a v i
  • 31. URL-centric design Clean URLs are stable URLs - your application’s public API (and part of the UI) http://example.com/products http://example.com/product/42 Design the URL scheme before coding. Configure application URLs in one file. Read it, bookmark it, mail it, tweet it. @PeterHilton • 29
  • 32. # HTTP routes configuration file ! GET / controllers.Application.index() ! GET /products controllers.Products.list() POST /products controllers.Products.add(p: Product) GET /product/:id controllers.Products.details(id: Long) DELETE /product/:id controllers.Products.delete(id: Long) ! GET /products.json controllers.Products.listJSON() GET /product/:id.json controllers.Products.detailsJSON(id:Long)
  • 33. User-interface architecture Think carefully about UI layer architecture Embrace HTML5 technologies Consider modern approaches: CoffeeScript instead of JavaScript LESS instead of CSS Twitter Bootstrap for consistent HTML. @PeterHilton • 31
  • 34. What’s worse than spaghetti code?
  • 35. Lasagne architecture! UI, web tier, services, business logic, model, database, etc plasticrevolver / CC BY-SA 2.0
  • 38. view URL routing controllers templates model database mapping HTTP queries renders presents calls
  • 39. Architecture summary A stateful web tier is not a cool thing Embrace HTTP-centric web architecture Beware of lasagne architecture Unlearn complexity and n-tier habits Combine multiple design perspectives UI-centric vs model-centric vs URL-centric Use cloud-ready architecture Leverage cloud tooling for running locally @PeterHilton • 37
  • 41. Optimising for time may cost you… CPU time vs programmer vs maintainer efficiency
  • 42. Writing Scala code Don’t worry about Scala style to start with (your code style will evolve anyway) Start with the syntax It takes a year to discover idiomatic style @PeterHilton • 40
  • 43. Writing code Spend time on code review or pair programming Don’t to be clever Aim for consistency Optimise code for maintainability @PeterHilton • 41
  • 44. Scala coding rules of thumb Immutability is your friend Learn to use functional style in methods … but don’t go overboard Humans need more info than the compiler … so add more variable names and types Use the REPL to try things out @PeterHilton • 42
  • 45. Scala coding recommendations Study the (immutable) collections API (ignore mutable collections) ! Put logic in pure functions and test those def calculateRiskScore (factors: List[Factor]): Int @PeterHilton • 43
  • 46. Scala coding recommendations Split large classes into traits ! Sometimes a Customer is just a NamedOrganisation ! Using more specific traits improves maintainability and compilation speed @PeterHilton • 44
  • 47. Play application code Keep controllers and templates lightweight Single-use view case classes: @PeterHilton • 45 ! case class ProductListView( id: Int, name: String, available: Boolean)
  • 48. Play application code Learn how to write custom components that work as if they were built-in: template formatters database column types body parsers - custom request body types writeables - custom HTTP response types @PeterHilton • 46
  • 49. // Code example: custom Play framework template formatters ! package templates ! object Formatters { ! // e.g. @updated.format in a template outputs ‘2013-­‐10-­‐25’ implicit class RichLocalDate(date: org.joda.time.LocalDate) { def format(): String = format("yyyy-­‐MM-­‐dd") def format(pattern: String) = date.toString(pattern) } ! // e.g. @price.format in a tempate outputs ‘EUR 2.99’ implicit class RichMoney(m: org.joda.money.Money) { import play.api.templates.Html def format = Html("${m.getCurrencyUnit.getCode}&nbsp;${m.getAmount}") }
  • 50. Third-party libraries There is no Father Christmas Hibernate. Seriously. ORM isn’t a Scala thing Learn the alternatives Slick is good but not particularly easy NoSQL persistence may be easier to use MongoDB, Neo4J, ElasticSearch, etc @PeterHilton • 48
  • 51. // Code example: Scala Slick database access ! // Nice: select * from LICENSE where id=? val query = Query(Licenses).filter(_.id === id)
  • 52. // Code example: Scala Slick database access ! // Nice: select * from LICENSE where id=? val query = Query(Licenses).filter(_.id === id) ! ! ! // Nasty: select b.NUMBER, b.DATE, p.NAME, o.NAME from BOOKING b // inner join ACCOUNT a on (a.ID=b.FROM_ID) // left outer join PERSON p on (p.ID=a.PERSON_ID) // left outer join ORGANISATION o on (o.ID=a.ORGANISATION_ID) val query = for { entry ← BookingEntries ((fromAccount, fromPerson), fromOrganisation) ← Accounts leftJoin People on (_.personId === _.id) leftJoin Organisations on (_._1.organisationId === _.id) if fromAccount.id === entry.fromId } yield ( entry.bookingNumber, entry.bookingDate, fromPerson.name.?, fromOrganisation.name.?)
  • 53. Lesson 4: Dev/prod environments
  • 54. Deployment infrastructure Move on from application servers Deploy to production before coding Cloud deployment for test/prod is easy Cloudbees, Heroku Databases are commodity cloud resources especially MySQL - Amazon RDS @PeterHilton • 51
  • 55. Development environment set-up example 1. Install dependencies: Java JDK 1.7, git, Play 2.1.3, MySQL 5.6 2. Clone GitHub repository https://github.com/HappyMelly/teller 3. Create MySQL database and user ! 4. Start application Play Evolutions SQL script initialises DB @PeterHilton • 52
  • 56. CloudBees deployment process example 1. Source code in GitHub repository 2. Develop code in feature branches 3. Merge commits to master after review 4. Automatic test deploy on push to GitHub 5. Smoke test on test server with prod data 6. Use Jenkins to promote the build to prod @PeterHilton • 53
  • 57. Deployment - dev environment Set-up your development environment as if you were doing an open-source project: Minimal steps to get started on a fresh machine, Idiot-proof instructions @PeterHilton • 54
  • 58. Deployment - prod environment Set-up your production environment as if you were deploying to the cloud: Match the development environment, Support continuous deployment, Automate deployment from the version control system @PeterHilton • 55
  • 60. 12 factors for cloud deployment @PeterHilton • 57 1. Codebase 2. Dependencies 3. Configuration 4. Backing services 5. Build/release/run 6. Processes 7. Port binding 8. Concurrency 9. Disposability 10. Dev/prod parity 11. Logs 12. Admin processes http://12factor.net
  • 62. Doing it the easy way Become Scala experts: Type system, compiler errors, OO vs FP ! Become Play experts: Try out most of Play’s features Learn how Play works internally Build ten experimental applications @PeterHilton • 59
  • 63. Doing it the hard way The same as the easy way, but without a year before the first real project ! Many new things at the same time is hard: uncertainty - especially unknown duration, risk - rework and operational issues @PeterHilton • 60
  • 64. Starting a project Enable high-productivity: Have very fast laptops - SSD, lots of RAM Match the team to the architecture: Keep both simple - at least to start with, Decide how to work with front-end devs, Have a Scala expert available Do experiments, or get help, to start faster @PeterHilton • 61
  • 65. M A N N I N G Covers Play 2 Peter Hilton Erik Bakker Francisco Canedo FOREWORD BY James Ward Play for Scala (Manning) ! Peter Hilton Erik Bakker Francisco Canedo ! http://bit.ly/playscala2p
  • 67. Reducing project risk - summary Community events - talking to other teams e.g. London Scala Users’ Group Read the book - don’t learn the hard way ! Attend the training course to learn faster Hire an expert to reduce project risk @PeterHilton • 64