Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Scaling business app development with Play and Scala
1. Scaling business app
development with
Play & Scala
@PeterHilton
http://hilton.org.uk/
2. 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
4. Business applications
Business applications support things like
data management,
process visibility and
process automation.
A special-purpose intranet application may
only have 10-100 users.
@PeterHilton • 4
5. Business app development projects
Development cost is the toughest issue.
@PeterHilton • 5
The following is a true story of how
Scala made us awesome.
Scaling is usually for runtime performance
This is not that talk.
6. With simplicity in the right places,
building a web application with the
Typesafe platform is* easier and
faster than with PHP
* probably
@PeterHilton • 6
9. Happy Melly
‘Happy Melly is a network of businesses
that self-organize around a purpose:
creating happy workers.’
http://www.happymelly.com/about/
Several member organisations
No head office or other central location
@PeterHilton • 9
13. Working with an experienced remote
product owner
@PeterHilton • 13
Release early:
no ‘sprint 0’ - first release on day one
Public Internet test server:
Play/Scala web app hosted on Cloudbees
Continuous delivery - release per feature
Push to master → test server deployment
14. Technical approach
Play Framework 2.1 (later upgraded to 2.2)
Scala 2.10 on JDK 1.7
Slick 1.0
MySQL 5.6
Twitter Bootstrap 2 (later upgraded to 3)
and some helpful libraries…
@PeterHilton • 14
23. private val FacebookDomain = "facebook.com"
private val LinkedInDomain = "linkedin.com"
private val GoogleDomain = "google.com"
private def validateDomain(url: String,
domain: String): Boolean = {
try {
val host = Option(new java.net.URI(url).
getHost).getOrElse("").toLowerCase
host == domain || host.endsWith("." + domain)
} catch {
case _: Throwable ⇒ false
}
}
val facebookProfileUrl = webUrl verifying
(error = "error.url.profile",
validateDomain(_, FacebookDomain))
24. Simplifying front-end development
Twitter Bootstrap
No custom CSS or JavaScript*
Master-detail pages
(HTML tables, straightforward layout)
Edit pages
(mostly standard Bootstrap form layout)
@PeterHilton • 20
* hardly any
26. How to cheat at front-end dev
We only supported the latest version of
Google Chrome
… and the usual pain just went away
Reminder: intranet application, few users,
and an experienced product owner.
@PeterHilton • 22
27.
28. // Code example: Scala Slick database access
// Nice: select * from LICENSE where id=?
val query = Query(Licenses).filter(_.id === id)
29. // 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.?)
30. Scalariform
Source code formatter, integrated with sbt
We liked it so much we set it up to
reformat code on every compilation and
replace ASCII art arrows with ⇒ and ←
@PeterHilton • 25
https://github.com/mdr/scalariform
31. // project/Build.sbt …
val main = play.Project(appName, appVersion, appDependencies
resolvers += Resolver.url("sbt-‐plugin-‐releases", url("
resolvers += Resolver.url("Objectify Play Snapshot Repository
resolvers += Resolver.url("Objectify Play Repository",
routesImport += "binders._"
).settings(
// Reformat code before every compilation :)
ScalariformKeys.preferences :=
FormattingPreferences().
setPreference(SpacesWithinPatternBinders, false).
setPreference(PreserveSpaceBeforeArguments, true).
setPreference(RewriteArrowSymbols, true)
)
32.
33. SecureSocial
Social network authentication:
Twitter, Facebook, Google, LinkedIn
Less effort and better UX than the usual
sign-up, log-in, reset password features
@PeterHilton • 28
http://securesocial.ws
34.
35. DataTables
HTML tables with client-side filter and sort,
in this case from server-side HTML tables.
http://datatables.net
DataTables-Bootstrap integrates styling.
http://datatables.net/manual/styling/bootstrap
@PeterHilton • 30
36.
37. pegdown & JSoup
Markdown processing - an easy way to use
standard HTML forms to edit HTML
https://github.com/sirthias/pegdown
JSoup sanitises the resulting HTML using
an HTML whitelist
http://jsoup.org
@PeterHilton • 32
38.
39. Joda Money
Currency arithmetic and conversion API.
Money type for an amount with a currency.
Arithmetic and currency conversion, with
an explicit rounding policy.
@PeterHilton • 34
http://www.joda.org/joda-money/
40. Lessons learned
You can save a lot of time on front-end
development if you cheat.
Development is very fast with two
experienced developers.
Slick had a steep learning curve* and
some scary queries, but we still liked it.
* writing/publishing Slick tutorials helped
@PeterHilton • 35
41.
42. One more thing…
Halfway through the project, the customer
decided to open source the application
https://github.com/happymelly/teller
@PeterHilton • 37
44. Netherlands Institute for
Innovative Ocular Surgery (NIIOS)
Independent eye surgery clinic in
Rotterdam, the Netherlands.
ISO accreditation requires quality
management and detailed reporting.
Status quo: lots of spreadsheets.
@PeterHilton • 39
45.
46.
47.
48.
49. Technical approach
Play Framework 2.2
Scala 2.10 on JDK 1.7
Slick 2.0
PostgreSQL 9.3
Twitter Bootstrap 2
… and jXLS, webjars, play-plugins-mailer
@PeterHilton • 44
51. jXLS
Parse and generate Excel spreadsheets
More useful than CSV because it supports
workbooks with multiple sheets
@PeterHilton • 46
Simplifying data maintenance with
spreadsheet integration
56. Lessons learned
Development is fast and predictable if
you’ve used the same architecture before.
‘We only support Chrome’ is possible twice.
One thing didn’t work: authentication via
NTLM challenge-response on Microsoft IIS
@PeterHilton • 51
58. Scale down
@PeterHilton • 53
High-performance technology can
scale down, as well as up.
Who knew?
It turns out that Play and Scala make
simple applications easier to build.
Bonus: maintainability and performance
59. Get Play framework benefits
Template system allows simple HTML and
using existing front-end frameworks.
HTML form validation API results in clear,
understandable code.
No XML.
@PeterHilton • 54
60. Get Scala benefits
Strong types capture the domain model
more explicitly and clearly (DDD FTW!)
Less verbose code, with immutable types,
is easier to debug and maintain.
Third-party Java libraries remain essential.
@PeterHilton • 55
61. Scale down the architecture
No web front-end development
(no custom JavaScript or CSS)
Standard action-based MVC
(server-side form validation only)
Database most familiar to the team
(avoid surprises and getting stuck)
No reactive programming
(would be premature optimisation here)
@PeterHilton • 56
64. Scaling down the scope
The first version of a business application
has a lot in common with a start-up’s MVP
(although a start-ups usually include front-end
dev and branding in ‘minimum viable’)
@PeterHilton • 59
65. Scaling up productivity
Throughput.
Cycle time.
One developer on the team needs to know
enough about agile software development
to be able to get people using the software
before the project gets cancelled.
@PeterHilton • 60
66. Scaling down the team
Scale down the architecture first.
The team size trade-off is:
communication overhead (big team)
vs
skills gaps (small team)
@PeterHilton • 61
67. Vertical and horizontal scaling
In this context, vertical scaling is about
making each developer more productive.
Horizontal scaling means more developers
… at the cost of exponentially increasing
overhead.
@PeterHilton • 62