Building a REST API in Java and Scala Using Play Framework – Part 1

building-a-rest-api-in-scala-and-java-using-play-framework-1In this two part series we explore Play Framework, and see how it can be used for rapidly developing RESTful APIs. In part one, we introduce Play, covering the main design decisions behind its architecture and potential reasons for choosing this framework over others. We’ll finish with a quick setup guide and a basic example. By the end of this first part you’ll have a feel for how easy it is to set up a REST API using Play.

In part two, we will delve deeper into Play’s features. We’ll use real world examples to show how to leverage Play’s unique capabilities. By the end of the series you should have a good grasp on API development using Play with ample resources to build your own REST API.

Introducing Play Framework 2

play framework-logoSo far on the blog, we’ve walked through using the Spark web framework to design APIs in Kotlin, Java, and Scala. It’s also hard to talk about building REST APIs on the Java Virtual Machine (JVM) without mentioning Play Framework. Play is an open-source web framework built in Scala and designed for both Java and Scala developers.

Despite the plethora of Java web frameworks already in existence at the time (Spring MVC, JSF, Google Web Toolkit, Grails…), French developer Guillaume Bort set out to build Play Framework in 2007. He took inspiration from frameworks for other programming languages like Rails (for Ruby) and Django (for Python) that were developer-friendly and well suited to rapid prototyping.

A RESTful Architecture

Play’s architecture is RESTful by default. At its core, Play is based on the Model-View-Controller pattern. Each entry point, paired with an HTTP verb, maps to a Controller function. The controller enables views to be web pages, JSON, XML, or just about anything else.

Play’s stateless architecture enables horizontal scaling, ideal for serving many incoming requests without having to share resources (such as a session) between them. It’s at the forefront of the Reactive programming trend, in which servers are event-based and parallel processing is used to cater to the ever-increasing demands of modern websites.

In certain configurations, Play enables fully asynchronous and non-blocking I/O throughout the entire application. The purpose is to reach new heights in terms of scalability on the web through efficient thread management and parallel processing, while avoiding the ‘callback hell’ that JavaScript-based solutions tend to engender.

In this first part of the Play Framework series, we’ll take a look at Play 2 in the context of building stateless REST services. Play also has an HTML template engine and all the tools needed to build fully fledged web applications, but we’ll focus on the features needed to build an API.

Download our free development guide

Why Play Framework 2?

Play Framework was built for both Scala and Java developers, and the code base is maintained in order to remain a viable alternative whether you use one language or the other.

Play’s pragmatism is one of its assets, much like it is for the Scala language. The fast iteration cycles and agile programming style it enables appeals to startup founders, but its familiarity to Java/JVM developers makes it a shoo-in for the corporate world and academia as well.

Here are some of the reasons why developers choose Play:

  • It leverages the JVM, a popular and mature execution environment, and all the libraries of the Java ecosystem,
  • It caters to a large developer population, spanning enterprise software, academia and startups,
  • It enforces type safety and encourages object-oriented design,
  • For Scala developers, it offers a great web framework based on functional programming – a paradigm that ensures the absence of side effects and promotes code succinctness,
  • It’s a great choice for API-first (RESTful) design,
  • It has an active community (Google groups, plugins…), though less so than major web frameworks like Node.js.

Play favors convention over configuration and no XML configuration files are needed to get up and running. It uses SBT for building and dependency management. It has a popular ‘auto-refresh’ feature that enables developers to test for compilation and runtime problems in the browser without restarting the server every time the code changes.

Play is lightweight by design – a lot of features that are built in most web frameworks have been isolated and packaged as plugins. It’s also easily extensible and enables multiple use cases and deployment scenarios – e.g. as a web application, the backend for a mobile app or as part of a microservices architecture.

There are multiple deployment options. Several cloud hosting providers — including Heroku and Jelastic — have Play-specific support, and it can easily be deployed to AWS Elastic Beanstalk, Google App Engine and Digital Ocean. Of course, you can just as easily self-host Play on your own servers.

As an official and commercially-supported part of Lightbend (formerly Typesafe), the company behind Scala and Akka, Play comes with options for professional production support, advanced monitoring tools and IDE plugins (including the official Scala IDE for Eclipse which includes Play-specific features). It also means it’s not going away anytime soon.

Many famous startups and news institutions now use Play — it’s especially present at companies where scalability is paramount — LinkedIn, Coursera, Hootsuite, Klout, LendUp, The New York Times, and The Guardian are all using Play for critical parts of their architecture.

A Basic Example

Now let’s look at some examples of building a REST API powered by Play. All examples in the below sections will be in Scala, although everything here is also possible in Java.

Play comes with an executable called ‘activator’, that enables developers to get up and running fast. It creates a basic folder structure, and provides a command line tool (or a graphical user interface) from which you can compile and run your Play application, or reload its configuration.

You don’t need to build anything special to expose a REST API — by default Play supports RESTful web services by enabling the developer to match an HTTP verb and an endpoint with a function defined in a custom controller via a flexible ‘routes’ file.

GET		/name				controllers.Application.getName

The above route maps the endpoint ‘/name’ and the HTTP verb GET to the getName function of the Application controller. Every time an incoming HTTP request hits the server, an Action is triggered, as defined in a Controller function. To serve the request described in our routes file, all we need to do is describe the getName function in the Application controller:

package controllers

import play.api._
import play.api.mvc._

object Application extends Controller {

  def getName = Action {
  	Ok("Jim")
  }

}

And there we have it — a simple REST API that returns the String “Jim” when the /name endpoint is requested.

The routes file supports regular expressions for flexible mappings. In the example below, we’ve used a regular expression to map an endpoint to a function only when the URL ends with a String of maximum 20 in length with either .JPG or .PNG as an extension:

GET 	/pics/$name<\w{1,20}\.(jpg|png)>	controllers.Application.getPicture(name: String)

Dealing with JSON

Play has native support for JSON and offers several options for developers looking to parse JSON into objects from the domain model.

You can parse and compose JSON objects manually:

def parseJson(json: JsValue) = Action { implicit request => 
  val name = (json \ "name").asOpt[String].get
  Ok("name : " + name)
}

But Play’s JSON library enables one to convert JSON objects into instances of Scala case classes automatically.

Play’s JSON library supports two-way mapping between JSON objects and Scala case classes. To demonstrate, let’s define a Person class with the following attributes.

case class Person(name: String, country: String, id: Int)

If we receive a JSON file such as the one below,

{
	name: “Jim Davis”,
	country: “United Kingdom”,
	id: 44952
}

we can easily read these values into an instance of the Person case class, using Play’s default converters:

def parseJson(json: JsValue) = Action { implicit request => 
  val person = json.read[Person] 
  Ok("name : " + person.name)
}

Let’s try a more complex, real world example. We’re going to parse a JSON file representing a Charge object from the popular Stripe payments API. The Charge object is complex and we only want to map it partially to a simple case class that fits the needs of our application.

In the example below we create a mapping between a JSON object representing a Stripe charge and a Scala case class. Note that we’re not mapping the whole JSON object — only the parts that we’re interested in.

import play.api.libs.json._
import play.api.libs.functional.syntax._

case class StripeCharge(id: String, created: Long, amount: Int, status: String, currency: String, 
	refunded: Boolean, maybeFailureMessage: Option[String], stripeCustomer: String) {

	implicit val stripeChargeReads: Reads[StripeCharge] = (
	  (JsPath \ "id").read[String] and
	  (JsPath \ "created").read[Long] and
	  (JsPath \ "status").read[String] and
              (JsPath \ "amount").read[Int] and
      	  (JsPath \ "currency").read[String] and  
              (JsPath \ "refunded").read[Boolean] and  
              (JsPath \ "failure_message").readNullable[String] and 
              (JsPath \ "customer").read[String] 
             )(StripeCharge.apply _)

}

Now that we’ve defined this custom mapping, we can call it implicitly when we want to turn JSON into an instance of this Scala class like we did before. This time we’re going to use json.validate instead of json.read. This enables us to manage potential exceptions when parsing the JSON object.

json.validate[StripeCharge] match {
 case c: JsSuccess[StripeCharge] => {
    val charge: StriepCharge = c.get
    Logger.info("Successfully parse Stripe charge: " + charge.id)
  }
  case e: JsError => {
    Logger.info("Error parsing Stripe charge: " + e.getMessage)
  }
}

Just as you can write implicit Reads to convert JSON into Scala objects, you can also create Writes to convert objects into JSON.

Continue to Part 2 For More

In Part 2 of this series, we’ll look at how Play handles synchronous and asynchronous web services, how it offers tools to combine and aggregate arbitrary computations to create rich backend applications, what options it offers for data persistence and streaming, and we’ll go through a list of tips and tricks to get the most out of Play. Sign up to our newsletter to make sure you don’t miss Part 2 in this series on using the Play Framework!