Play vs. Grails Smackdown James Ward and Matt Raible and Changelog September 24, 2013: Updated for . March 24, 2013: Updated and for . June 24, 2012: . June 19, 2012: Published for . @_JamesWard @mraible statistics JavaOne statistics load tests Devoxx France Play Performance Fix ÜberConf
The Play vs. Grails Smackdown. A comparison done by James Ward and Matt Raible. Includes detailed analysis from building the same webapp with these two popular JVM Web Frameworks.
See the HTML5 version of this presentation at http://www.ubertracks.com/preso.
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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 RequirementsServer-side TemplatesPlay 2 with JavaForm ValidationData PaginationAuthenticationScheduled Jobs
Atom / RSSEmail NotificationsUnit / Integration TestsLoad TestsPerformance Tests
Stretch Goals: Search, Photo Upload to S3
Our ScheduleWeek 1 - Data Model DefinitionWeek 2 - Data Layer & URL DesignWeek 3 - Controllers & AuthWeek 4 - ViewsWeek 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 resourceconsumption (CPU, memory, threads) for highly-
scalable applications.”
My Top 10 Favorite Features1. Just hit refresh workflow2. Type safety3. RESTful4. Stateless5. Reactive6. Asset Compiler7. First-class JSON8. Java & Scala9. Templates in Activator
10. LinkedIn, Gawker, etc
Intro to Grails 2
“ Powered by Spring, Grails outperforms thecompetition. Dynamic, agile web development
without compromises. ”
My Top 10 Favorite Features1. Documentation2. Clean URLs3. GORM4. IntelliJ IDEA Support5. Zero Turnaround6. Excellent Testing Support7. Groovy8. GSPs9. Resource Optimizer
10. Instant Deployment on Heroku
Our SetupIntelliJ IDEA for DevelopmentGitHub for Source ControlCloudBees for Continuous IntegrationHeroku for Production
Later added: QA Person and BrowserMob
Code Walk ThroughWe developed the same app, in similar ways, so let's look at the
different layers.
↓
DatabaseURL MappingModelsControllersViewsValidationIDE Support
Database - PlayEBean is the default persistence provider in Java projectsEvolutions can be auto-appliedInitial evolution sql is auto-createdSubsequent changes must be versionedAuto-created schema file is database dependentPlay 2 supports multiple datasources (Play 1 does not)
public static Result signup() { Form<User> signupForm = form(User.class).bindFromRequest(); if (signupForm.hasErrors()) { return badRequest(views.html.signupForm.render(signupForm)); }
MailerAPI mail = play.Play.application().plugin(MailerPlugin.class).email();mail.setSubject("Uber Tracks Region Updates");mail.addRecipient(regionUserDigest.user.getEmailAddress());mail.addFrom("[email protected]");mail.send(emailContent);
Testing - GrailsUnit Tests with @TestFor and @MockTest URL Mappings with UrlMappingsUnitTestMixinIntegration Testing with GroovyTestCaseFunctional Testing with Geb
* Grails plugins often aren't in test scope.
test/unit/happytrails/RouteTests.groovy
package happytrails
import grails.test.mixin.*
@TestFor(Route)class RouteTests {
void testConstraints() { def region = new Region(name: "Colorado") def whiteRanch = new Route(name: "White Ranch", distance: 12.0, location: "Golden, CO", region: region) mockForConstraintsTests(Route, [whiteRanch])
// validation should fail if required properties are null def route = new Route() assert !route.validate() assert "nullable" == route.errors["name"]
S3Blob.initialize(application); // load the demo data in dev mode if no other data exists if (Play.isDev() && (User.find.all().size() == 0)) { DemoData.loadDemoData(); }
Configuration - PlayBased on the TypeSafe Config LibraryOverride config with Java Properties:-Dfoo=barEnvironment Variable substitutionRun with different config files:-Dconfig.file=conf/prod.conf
// Added by the Spring Security Core plugin:grails.plugins.springsecurity.userLookup.userDomainClassName = 'happytrails.User'grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'happytrails.UserRole'grails.plugins.springsecurity.authority.className = 'happytrails.Role'
Application ComparisonYSlowPageSpeedLines of CodeLoad TestingWhich Loads Faster?Security Testing
YSlow
PageSpeed
Lines of Code
Load Testing withBrowserMob
Bike (Grails) Hike (Play)
Load Testing - 1 Dyno
Load Testing - 1 Dyno
Bike (Grails) Hike (Play)
Load Testing - 5 Dynos
Load Testing - 5 Dynos
Load Testing - 2 Dynos (March2013)
GrailsPlay Framework
0 700 1,400 2,100 2,800
Requests / Second
Load Testing - 2 Dynos (Sept2013)
GrailsPlay Framework
0 70 140 210 280
Requests / Second
Load Testing - 5 Dynos + 100users
Which Loads Faster?
Which Actually Loads Faster?
Pen Testing with OWASP ZAP
Grails 2 vs. Play 2JobsLinkedIn SkillsGoogle TrendsIndeedMailing List TrafficBooks on Amazon2012 ReleasesStack OverflowHacker News
Jobs
September 22, 2013
GrailsPlay FrameworkSpring MVC
0 400 800 1,200 1,600
Dice
Monster
Indeed
LinkedIn Skills
September 22, 2013
# People
4,000 8,000 12,000 16,000 20,000
Grails
Play Framework
Spring MVC
Google Trends
Grails Play
Indeed Job Trends
User Mailing List Traffic
GrailsPlay Framework
700 900 1,100 1,300 1,500
March
April
May
June
July
August
Books on Amazon
September 2013
GrailsPlay Framework
3
11
2013 Releases
GrailsPlay Framework
8
10
2012 Releases
GrailsPlay Framework
6
9
StackOverflow Questions
grailsplayframework
5149
12978
Hacker News
Grails 2.0 releasedPlay Framework 2.0 Final released6
195
Conclusions: CodeFrom 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, especiallyroutes and upgrades.
Conclusions: StatisticalAnalysis
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: EcosystemAnalysis
"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 isnarrowing.We had similar experiences with documentation andquestions.Outdated documentation is a problem for both.Play has way more hype!