Our project
www.waduno.de - short for "what you know" - is a german-speaking website for proving IT and business skills. By mastering several tests, you get scores and can publish them on social networks, your own website or in your resume. In the long run, we enable candidates to enrich their resumes which trustworthy quantitative skill information.
We started waduno by closely following the lean startup methods. In order to provide the high-speed iterations required for a fast validated learning cycle, we needed a highly productive web framework. Ruby on Rails was a natural first choice. But since we are more familiar with the Java world, we looked around and fell in love with Play!
Though it is of course a risk to try a brand new technology for a serious project, our first tests were so promising, we couldn't resist. Just open your browser on your newly created application, change whatever you like, templates, code or configuration, reload - and there you are. It is hard to describe the boost of freedom in development you get from this feature - you have to try!
Basics
The MVP model looks familiar if you accept static methods as manifestations of the stateless architecture. The Play! people did such a good job in simplifying standard tasks. Let's as an example look at the code to save a business object, which is itself of course represented as a Model class:
package models; import javax.persistence.Entity; import play.db.jpa.Model; @Entity public class Person extends Model { public Date created; @Required @Email @Column(unique = true) public String email; @Required public String password; @Required @Column(unique = true) public String name; public int score; @ManyToOne public Company company; public static Person findByMailDomain(String domain) { return Person.find("email like ?", "@"+domain).fetch(); } public void upgrade(String msg) { score++; Event.log(this, msg); this.save(); } }From that simple example, you can observe several key aspects of Play! models:
- Persistence is done with JPA
- The Model base class provides ID handling
- Several validation annotations are available
- No anemic models: You find the business code in the model, not in services.
- Querying is simple using find()-methods
- the dirty state model is inverted when compared to hibernate et. al.: Objects are only save after an explicit call to save()
#{extends 'main.html' /} #{set title:'waduno - New Quiz!' /} #{form @UserAdmin.save()} <input type="hidden" name="person.id" value="${person?.id}"/> <div class="region"> Name:<br> <input type="text" class="big #{errorClass 'person.name'/}" name="person.name" id="title" value="${person?.name}"/> <br> <!-- lots of other fields --> </div> #{/form}
Here you can see:
- Play has templates, Groovy based, that can be extended (main.html in this case) and parameterized
- It can construct URLs for server methods for you (@UserAdmin.save())
- Simple error handling, e.g. by #{errorClass ...}
public static void saveQuestion(@Valid Person person) { if (validation.hasErrors()) renderTemplate("@edit", person); person.save(); show(person.id); } public static void show(Long id) { Person person = Person.findById(if); render(person); }
Isn't that extremely simple to understand?
- Play! takes the person.id request Parameter and loads the Person from the database
- It applies the remaining request parameter to the object
- ... validates the object
- ... and the passes it to the controller method
- The method the shows the form again if validation failed
- ... or saves the updated object
- ... and the applies Post-Redirect-Get. Yes, by simply calling another controller method show().
Our experiences
It really was fun to develop with Play! We needed one man-month to come up with a first MVP-iteration (and we mostly worked on the graphical design ;-). Variations of flow, output or business logic could be implemented very fast.
We even saw developers and product managers sitting side by side in front of a monitor, trying features and developing in real time! This way not only productivity is boosted, but the whole team gets a much better understanding of product features and technical possibilities.