Building a Simple REST API with Scala & Play! (Part 1)
By Justin Rodenbostel
In this 3 part series, we’ll cover creating a basic Play! REST API on top of Reactive Mongo. Full source code for this tutorial is available at https://github.com/jrodenbostel/getting-started-play-scala.
Why Scala & Play!?
There has been a lot of buzz recently in the industry and at our some of our clients around Reactive Programming and related frameworks. Reactive Programming is a movement based around building applications that can meet the diverse demands of modern environments. The four main characteristics are:
- Responsiveness: high-performance, with consistent and fast response times
- Resilience: fails gracefully, and remains responsive during failures
- Elasticity: remains responsive during varying workload
- Message Driven: non-blocking, back-pressure capable, asynchronous
Moves towards cloud infrastructure, microservices architecture, and DevOps-style tools which have made conveniences of previously cumbersome tasks, all lend themselves to supporting reactive systems: systems composed of many small pieces, possibly distributed, expanding and contracting based on load, location agnostic, relying on messaging to communicate. Maybe you’ve seen parts of this and haven’t realized it has a name. Systems designed based on these principles can be considered reactive.
Like many things in development, learning a new tool or technique often requires not only reading, but also coding a live example. In this blog series, I’ll cover creating a small, simple reactive system – a simple RESTful API using the Play! Framework and Reactive Mongo. Because reactive programming is often associated with functional programming, I’ll also be writing this example in Scala.
The Play! Framework (https://playframework.com) is an open source web app framework that’s been around since 2007. In many ways, it’s similar to other web application frameworks you may be familiar with like Spring MVC and Rails: it’s MVC-based, it comes with a lot of built-in support tooling (scaffolding, execution, dependency management, etc), and it’s based on the principle of convention over configuration. In other ways, mostly ways that indicate how it fits into the world of reactive systems, it differs from those frameworks: it’s 100% stateless and is built to run on Netty (http://netty.io) – a non-blocking, asynchronous application framework.
Behind Play!, Reactive Mongo (http://reactivemongo.org) will give us non-blocking and asynchronous access to a Mongo document store through a Scala driver and a Play! module for easy integration into a Play! apps. The Reactive Mongo API exposes most normal data access functions you’d come to expect, but returns results as Scala Futures, and provides translation utilities for translating the Mongo document format (BSON) to JSON, and many functional helper methods for dealing with result sets.
To wrap it all up, we’ll be using Spec2 (https://etorreborre.github.io/specs2/) to unit and integration test our application. Spec2 allows us to write test cases in the style of behavior-driven development and highlights the flexibility of Scala and how it an easily be used to create a domain-specific language.
You may find the tools in this tutorial more difficult to get started with than others you may be used to – there are many new concepts in the mix here – it’s to be expected. These tools have a place in a creating highly-available, fault-tolerant systems capable of handling web-scale traffic. If you were actually building what we’ll build in this tutorial, this may not be the right tool set.
To get started, make sure you have Scala installed. There are many ways to install Scala. My favorite is by using the Homebrew package manager available for the Mac (http://brewformulas.org/Scala). You can also download, unpack binaries, and update paths by following the instructions here (http://www.scala-lang.org/download/install.html).
You’re also going to want to have Mongo installed. Again, this is something that I normally install using the Homebrew package manager. More detailed instructions can be found here: https://docs.mongodb.org/manual/tutorial/install-mongodb-on-os-x/. You should obviously have Mongo running during this tutorial.
Assuming Scala is installed, next download and install the Typesafe Activator, available here (https://www.typesafe.com/activator/download). This will give us a nice UI for generating our application, running and viewing the results of tests, and running our application.
After installing the Typesafe Activator, open a command line prompt and start it up:
Justins-MacBook-Pro:Projects justin$ activator ui
From the Typesafe Activator window, under the ‘Templates’ menu item, select ‘Seeds’, then select ‘Play Scala Seed’. Don’t forget to give your application a name and location before hitting the ‘Create app’ button.
After pressing the ‘Create app’ button, you should be greeted with a message indicating that your application was created successfully. From this window, we’ll be able to start/stop, compile, and test our new application. Remember, Play! supports hot-swapping of code, so we’ll be doing a lot of viewing results in this window.
Play! applications generated from the Play! Scala seed that we just used come packed with a pre-defined build script written using SBT. SBT is the de-facto build tool for Scala applications from Typesafe. More information on SBT can be found here (http://www.scala-sbt.org). Our new application has a build.sbt file that we’ll need to update with a dependency for Reactive Mongo. Update the library dependencies sequence in build.sbt accordingly:
libraryDependencies ++= Seq( jdbc, cache, ws, specs2 % Test, "org.reactivemongo" %% "play2-reactivemongo" % "0.11.7.play24" )
Much like Maven or Bundler, this will automatically download and install the Reactive Mongo Play! module, which will in turn download the necessary dependent Reactive Mongo and Mongo libraries.
Next, we’ll update our application.conf file to include configuration information about our Mongo instance. The application.conf file is found at /conf/application.conf and contains generally configuration settings for your application. We have two lines to add to this file. Add the following at the end of application.conf and save your changes:
play.modules.enabled += "play.modules.reactivemongo.ReactiveMongoModule" mongodb.uri = "mongodb://localhost:27017/getting-started-play-scala"
At this point it’s probably worth noting that if you’re interested in exploring or manipulating a Mongo instance, I recommend using Robomongo (http://robomongo.org).
To conclude part 1, using the Typesafe Activator, run your application. If we’ve installed our dependencies correctly, we should be greated with the default Welcome to Play screen, as seen below:
Please continue to part 2, where we’ll begin to define our REST API by creating a Play! controller with asynchronous actions, and then move on to creating our data access layer using Reactive Mongo.