Play vs. Grails Smackdown

James Ward and Matt Raible

@_JamesWard and @mraible

Theme: Sky - Beige - Simple - Serif - Night - Default

Why a Smackdown?

Play 2 and Grails 2 are often hyped as the most productive JVM Web Frameworks.

* We wanted to know how they enhanced the Developer Experience (DX).

Happy Trails Requirements


  • Server-side Templates
  • Play 2 with Java
  • Form Validation
  • Data Pagination
  • Authentication
  • Scheduled Jobs
  • Atom / RSS
  • Email Notifications
  • Unit / Integration Tests
  • Load Tests
  • Performance Tests

Stretch Goals: Search, Photo Upload to S3

Our Schedule

  • Week 1 - Data Model Definition
  • Week 2 - Data Layer & URL Design
  • Week 3 - Controllers & Auth
  • Week 4 - Views
  • Week 5 - Misc Polish

Intro to Play 2


Play Framework is based on a lightweight, stateless, web-friendly architecture. Built on Akka, Play provides predictable and minimal resource consumption (CPU, memory, threads) for highly-scalable applications.

My Top 10 Favorite Features

  1. Just hit refresh workflow
  2. Type safety
  3. RESTful
  4. Stateless
  5. Reactive
  6. Asset Compiler
  7. First-class JSON
  8. Java & Scala
  9. Templates in Activator
  10. LinkedIn, Gawker, etc

Intro to Grails 2

Powered by Spring, Grails outperforms the competition. Dynamic, agile web development without compromises.
Powered by Spring, Grails outperforms the competition. Dynamic, agile web development without compromises.

My Top 10 Favorite Features

  1. Documentation
  2. Clean URLs
  3. GORM
  4. IntelliJ IDEA Support
  5. Zero Turnaround
  6. Excellent Testing Support
  7. Groovy
  8. GSPs
  9. Resource Optimizer
  10. Instant Deployment on Heroku

Our Setup

  • IntelliJ IDEA for Development
  • GitHub for Source Control
  • CloudBees for Continuous Integration
  • Heroku for Production

Later added: QA Person and BrowserMob

Code Walk Through

We developed the same app, in similar ways, so let's look at the different layers.


Database - Grails

  • Hibernate is the default persistence provider
  • Create models, Hibernate creates the schema for you

grails-app/conf/DataSource.groovy

Database - Play

  • EBean is the default persistence provider in Java projects
  • Evolutions can be auto-applied
  • Initial evolution sql is auto-created
  • Subsequent changes must be versioned
  • Auto-created schema file is database dependent
  • Play 2 supports multiple datasources (Play 1 does not)

conf/evolutions/default/2.sql

Database - Play

Using Heroku Postgres in production rocks!

  • Postgres 9.1
  • Dataclips
  • Fork & Follow
  • Multi-Ingres

URL Mapping - Grails

grails-app/conf/UrlMappings.groovy

URL Mapping - Play

conf/routes

Models - Grails

  • All properties are persisted by default
  • Constraints
  • Mappings with hasMany and belongsTo
  • Override methods for lifecycle events

grails-app/domain/happytrails/Region.groovy

Models - Play

  • EBean + JPA Annotations
  • Declarative Validations (JSR 303)
  • Query DSL
  • Lazy Loading (except in Scala Templates)

app/models/Direction.java

Controllers - Grails

grails-app/controllers/happytrails/HomeController.groovy

Controllers - Play

  • Stateless - Composable - Interceptable
  • Clean connection between URLs and response code

app/controllers/RouteController.java

Views - Grails

  • Groovy Server Pages, like JSPs
  • GSP Tags
  • Layouts and Templates
  • Optimized Resources

grails-app/views/region/show.gsp

Views - Play

  • Scala Templates
  • Composable
  • Compiled

app/views/region.scala.html

Validation - Grails

grails-app/controllers/happytrails/RouteController.groovy

grails-app/views/route/create.gsp

Validation - Play

app/controllers/RouteController.java

app/views/signupForm.scala.html

IDE Support - Grails

IntelliJ Rocks!

IDE Support - Play


  • $ play idea
  • $ play eclipsify

  • Java!!!
  • Debugging Support via Remote Debugger
  • Limited Testing within IDE

Job - Grails

grails-app/jobs/happytrails/DailyRegionDigestEmailJob.groovy

Job - Play


  • Plain old `static void main`
  • Independent of web app


app/jobs/DailyRegionDigestEmailJob.java

Feed - Grails

  1. grails install-plugin feeds
  2. Add feed() method to controller

grails-app/controllers/happytrails/RegionController.groovy

Feed - Play


  • No direct RSS/Atom support
  • Dependency: "rome" % "rome" % "1.0"

app/jobs/DailyRegionDigestEmailJob.java

Email - Grails

grails-app/jobs/happytrails/DailyRegionDigestEmailJob.groovy

* powered by the mail plugin (built-in)

Email - Play

  • SendGrid Heroku Add-on
  • Dependency:
    "com.typesafe" %% "play-plugins-mailer" % "2.0.2"

app/jobs/DailyRegionDigestEmailJob.java

conf/prod.conf

Photo Upload - Grails

Photo Upload - Play

  • Amazon S3 for Persistent File Storage

app/models/S3Photo.java

app/controllers/RegionController.java

Testing - Grails

  • Unit Tests with @TestFor and @Mock
  • Test URL Mappings with UrlMappingsUnitTestMixin
  • Integration Testing with GroovyTestCase
  • Functional Testing with Geb

test/unit/happytrails/RouteTests.groovy

* Grails plugins often aren't in test scope.

Testing - Play

  • Standard JUnit
  • Unit Tests & Functional Tests
  • FakeApplication, FakeRequest, inMemoryDatabase
  • Test: Controllers, Views, Routing, Real Server, Browser

test/ApplicationControllerTest.java

Demo Data - Grails


grails-app/conf/BootStrap.groovy

Demo Data - Play


app/Global.java

Configuration - Grails

grails-app/conf/Config.groovy

Configuration - Play

  • Based on the TypeSafe Config Library
  • Override config with Java Properties:
    -Dfoo=bar
  • Environment Variable substitution
  • Run with different config files:
    -Dconfig.file=conf/prod.conf

conf/prod.conf

Authentication - Grails

Spring Security UI Plugin, I love you!

grails-app/conf/Config.groovy

Authentication - Play

  • Uses cookies to remain stateless

app/controllers/Secured.java

app/controllers/RegionController.java

Application Comparison

YSlow

PageSpeed

Lines of Code

Load Testing with BrowserMob

Load Testing - 1 Dyno

Bike (Grails)

Hike (Play)

Load Testing - 1 Dyno

Load Testing - 5 Dynos

Bike (Grails)

Hike (Play)

Load Testing - 5 Dynos

Load Testing - 2 Dynos (March 2013)

Load Testing - 2 Dynos (Sept 2013)

Load Testing - 5 Dynos + 100 users

Which Loads Faster?

Which Actually Loads Faster?

Pen Testing with OWASP ZAP

Grails 2 vs. Play 2

Jobs

LinkedIn Skills

Google Trends

Grails Play

Indeed Job Trends

User Mailing List Traffic

Books on Amazon

2013 Releases

2012 Releases

StackOverflow Questions

Hacker News

Conclusions: Code

  • From a code perspective, very similar frameworks.
  • Code authoring good in both.
  • Grails Plugin Ecosystem is excellent.
  • TDD-Style Development easy with both.
  • Type-safety in Play 2 was really useful, especially routes and upgrades.

Conclusions: Statistical Analysis

  • Grails has better support for FEO (YSlow, PageSpeed)
  • Grails has less LOC! (4 more files, but 20% less code)
  • Apache Bench with 10K requests (2 Dynos):
    • Requests per second: {Play: 242, Grails: 257}
  • Caching significantly helps!

Conclusions: Ecosystem Analysis

  • "Play" is difficult to search for.
  • Grails is more mature.
  • Play has momentum issues.
  • LinkedIn: more people know Grails than Spring MVC.
  • Play had 3x user mailing list traffic, but gap is narrowing.
  • We had similar experiences with documentation and questions.
  • Outdated documentation is a problem for both.
  • Play has way more hype!

Questions?

* Presentation created with Reveal.js, Google Charts and GitHub Files.

Action!

Learn something new*!

* Or prove that we're wrong...