Welcome back!

We finished parts 1 & 2, which started with a description of the tools we’ll be using, and concluded with a fully functioning REST API built in Play! on top of a Reactive Mongo back-end. In part 3, we’ll cover the use of Spec2 and Mockito to write automated unit and integration tests for our application.

Integration Testing

Spec2 provides a DSL for BDD-style test specs. One variation of these specs, WithBrowser, actually runs the code in a headless browser, allowing you to end-to-end test your application in automated fashion. To get started, open the ‘/test/IntegrationSpec.scala’ file, which was created as part of our seed project. Update it to include the following:

You’ll notice a spec for each Application Controller function, which simply visits the relevant URI and matches the response string. Tests can be executed from the Activator UI or by running ‘activator test’ from the command line from within your project folder.

Unit Testing

Unit testing is a bit more complex because we’ll test each controller by mocking the relevant repository method. Assertions for unit tests are more straightforward, as in most cases, we’re simply inspecting HTTP status codes. Update the ‘test/ApplicationSpec.scala’ file to include the following:

You’ll notice the class starts with the creation of Mocks and example data – this is very straightforward and was pulled from examples of real BSON data from Mongo. In each spec, you’ll also notice the same pattern: mocks are configured, methods are exercised, and assertions are made. Very similar to other BDD-style test frameworks like Jasmine and Rspec.

Conclusion

Reactive programming and related frameworks, especially those of the functional variety, represent a significant shift in the way we write applications. There are many new patterns, tools, and programming styles that a developer must become familiar with in order to write applications in the reactive style effectively. Many of us, myself included, are just starting to get opportunities to do so. Although these tools may not be appropriate for every solution, becoming familiar with the underlying concepts will help individuals become more well-rounded as developers and help ensure that scalable, resilient, responsive architectures are adopted when necessary.

Welcome back!

If you’re coming in fresh, and need some instructions on getting the appropriate tools installed and creating a shell of an environment, please refer to part 1. In part 2, we’ll cover adding our first API functions as asynchronous actions in a Play! controller, as well as define our first data access functions.

Because we started with a seed project, we got some bonus cruft in our application in the form of a views package. While Scala templates are a fine way to create views for your application, for this tutorial, we’ll be building a RESTful API that responds with JSON strings. Start by deleting the ‘views’ folder at ‘app/views’ such that:

Note that this will break the default controller that came as part of the project seed. To remedy this, update the default controller action response to simply render text, by replacing:

Ok(views.html.index("Your new application is ready."))

with:

Ok("Your new application is ready.")

Creating the controller

Next, we’ll create our controller. Create a new file in the ‘app/controllers’ folder named ‘Widgets.scala’. This will house the RESTful actions associated with Widgets. We’ll also add default methods to this controller for the RESTful actions that we’ll implement later.

Play! comes with a default “TODO” page for controller actions that have not yet been implemented. It’s a nice way to keep your app functioning and reloading while you’re building out functionality incrementally. Before we can see that default “TODO” page, we must first add routes to the application configuration that reference our new controller and it’s not-yet-implemented actions.

Update /conf/routes with paths to the Widgets controller such that the following is true:

Now, we can visit one of these new paths to view the default “TODO” screen.

Data access

Before we can build out our controller actions, we’ll add a data access layer to surface some data to our controller. Let’s start by creating the trait, which will define the contract for our data access layer. (Traits are similar to Interfaces in Java – more info that here http://docs.scala-lang.org/tutorials/tour/traits.html)

Create a new folder called ‘repos’ such that a directory at ‘app/repos’ exists. In that directory, create a new Scala file named WidgetRepo.scala with the following content:

Again, there shouldn’t be much that’s surprising here other than the normal, somewhat complex IMO, Scala syntax. You can see the implicit ExecutionContext, which, for asynchronous code, basically let’s Scala decide where in the thread pool to execute the related function. You may also notice the ReadPreference in the find() function. This tells Mongo that our repo would like to read it’s results from the primary Mongo node.

Back to the controller

At this point, we can return to our controller to round out the implementation details there. Let’s start simple.

Before we can start adding implementation details, we need to configure some dependency injection details. We’ll inject the ReactiveMongoApi into our Controller, then use that to create our repository. Update the signature of the Widgets controller and imports so the following is true:

In ‘app/controllers/Widgets.scala’, we have an unimplemented ‘index’ function. This is meant to display a list of all widgets in the database, selected without parameters. The implementation for this function is very straightforward. Update the index function such that:

In this implementation, since we’re expecting a single result, when we execute ‘map’ on the result, we’ll take the resulting object and render it directly to our JSON response.

The ‘read’ method, which is very similar to ‘index’, will take a single String parameter (the id of the document being searched for) and return a single result as JSON string. Update the read function such that:

The ‘create’ and ‘update’ methods introduce a small amount of complexity in that they require the request body to be parsed using Scala’s built in pattern matching functionality. Since we’ll have to match the field names in two places, we’ll create a companion object to hold our field names. Create a ‘WidgetFields’ companion object in the Widgets controller source file:

Execution of this method returns the HTTP status code 201. For the ‘update’ method, we’ll perform largely the same operation – applying the JSON Body Parser to an implicit request, however, this time we’ll call a different repo method – this time building a BSONDocument to select the relevant document with, then passing in the current field values:

Testing!

Part 3 of this series will cover testing using the Spec2 library. In the mean time…We have a fully functioning REST API – but testing manually requires configuration and the execution of HTTP operations. Many web frameworks are packed with functionality that allows a developer to ‘bootstrap’ an application – adding seed data to a local environment for testing as an example. Recent changes in the Play! framework’s GlobalSettings have changed the way developers do things like seed test databases (https://www.playframework.com/documentation/2.4.x/GlobalSettings). While the dust settles, and while we wait for part 3, I created some helper functions in the Application controller that will create and remove some test data:

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.

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.

Installing Dependencies

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:

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: