The Play Framework at LinkedIn
I’m excited to announce the next step in LinkedIn’s service infrastructure: the Play Framework. Play is a modern web framework that combines the performance and reliability of Java and Scala, the power of reactive programming, and the productivity of full hot reload support.
We’ve been running Play 2.0 in production for several months and are now gradually rolling it out to more teams at LinkedIn. In this blog post, I'll talk about the benefits we've seen from Play, show a brief walk-through of the developer experience, and talk about our future plans.
Play offers a lightweight framework for building scalable services that are easy to maintain; what makes it magical, however, is that it does this without sacrificing developer productivity. Building web services with Java and Scala can actually be fun!
Here are some of the features we love:
- Rapid iteration: change the code, refresh the page, and see the change instantly.
- Java and Scala: JVM performance, type safety, libraries, IDE/tooling support, huge community.
- Reactive: non-blocking IO makes parallel data fetch easy and real-time web possible.
- Open: github repo, documentation, user group, open source plugins, and StackOverflow.
- Supported: Typesafe and Zenexity provide commercial support for Play.
- Flexible: almost everything is pluggable, configurable, and customizable.
A Tour of Play
Let's walk through a quick tour of developing apps with Play. Play has idiomatic support for both Java and Scala; this tutorial will start with some Java examples in the first half and move onto Scala for the second half.
1. Create an app
Follow the install instructions to get the Play executable installed. Create a new app called
play-tutorial using the
play new command:
2. Run the app
cd into the
play-tutorial directory, use
play run to fire up the server, and open http://localhost:9000 in your browser:
At this point, you can load up the source code for the play-tutorial project in your favorite IDE.
3. Say "Hello World"
Play follows an MVC pattern, so we’ll start by creating a controller called
Controllers consist of actions, or methods, that return a
Result. In the code above, we’re just returning a simple
200 OK with the text “Hello World” as our
All we need to do now is to expose this controller/action at a URL. You do this by adding an entry to the
routes file in the
The format here is an HTTP method, followed by a URL pattern, followed by the actual controller/action code to execute.
Open http://localhost:9000/hello to test out your new route. Play will automatically reload the Java and routes file changes and you should see the results in your browser in seconds:
4. Read the query string
Let’s make things slightly more dynamic by reading a query string parameter from the URL. First, add a parameter to the
index action in
To specify that this parameter comes from the query string, modify the
Now open http://localhost:9000/hello?year=2013 in the browser, and you’ll see this:
Note that Play will check the parameter types for you. For example, try the URL http://localhost:9000/hello?year=garbage and you’ll see:
5. Make a mistake
This is a good time to point out one of our favorite features about Play: you can see error messages right in the browser instead of hunting for them in a log file. For example, let’s say you have a typo in your Java code where you forgot a semi-colon. When you refresh the page, you'll see:
If you make a mistake in a Java class, Scala class, routes file, template code, or just hit an exception, Play shows the error message, the line number, and even the relevant code right in the browser window.
6. Render a view
Let’s add a view for the
HelloWorld controller to render. Play has Scala templates built-in, so we’ll create
index.scala.html in the
@ syntax at the top lets you pass data from the controller to the view for rendering. Update the
HelloWorld controller to render the
index view and pass the date parameter to it:
Refresh http://localhost:9000/hello?year=2013 in your browser and you should see this page:
7. Try out Scala
If you prefer Scala to Java, Play has you covered. Let’s create the skeleton of a Scala controller called
We’ll use Play’s WebServices library to make non-blocking calls to a URL passed in as a query string parameter and return the response body as our
Result, effectively proxying a website:
Let’s add a
/proxy endpoint in our routes file:
Now try http://localhost:9000/skeleton/proxy?path=http://engineering.linkedin.com/play/play-framework-linkedin in your browser. You should see this very blog post!
8. Go parallel
The HTTP calls we made above with the
WS library were non-blocking. This means it’s easy to make multiple calls in parallel. Let’s add a new Scala controller called
Race that will make parallel calls to a few search engines and return JSON reporting how long it took to get a response from each one:
Now add a
Finally, open up http://localhost:9000/race and see who’s fastest.
We've found that Play is one of the few frameworks that is able to maintain the delicate balance of performance, reliability, and developer productivity. As we continue rolling out Play to the entire company and deploying more services, we will be writing about our experiences on this blog.
We're proud to be actively contributing pull requests to Play and will be ramping up our contributions even more in the future. We'll also be releasing a number of open source plugins. Early versions of the dust.js and testng plugins are already available, with many others - including rest.li integration, parseq support, and a new assets pipeline - coming soon.
Update: read on to learn about Play Framework and async I/O without the thread pool and callback hell.