anaa yoo @ flickr.com

In the previous part of this series I talked about how to start moving your existing Play application towards more functional solution. We started simply, introducing IO from the famous Cats library.

The change was pretty simple, yet very powerful, allowing us to use the power of referential transparency versus Future based mess we often encounter, especially in existing code bases.

Today we will move one step further and start using Tagless Final pattern to further abstract our interfaces and prepare our application for easier and more extensive testing. The main issue when using Tagless Final in existing Play application is the problem with built-in dependency injection — of course we will fix it but more on that later.

We are going to add some new packages like repositories and services and possibly more, to further divide our source files into a bit more meaningful groups.

Let’s start using the tagless final pattern and create PersonRepository interface with all the method declarations we need:

As you can see, we are no longer bound to a specific effectful type like IO but to a higher kinded type F[_] . We can create concrete implementations for our interface when needed, eg: InMemoryPersonRepository for test purposes or SlickPersonRepository for database Slick library usage (more on that later).

As we are expecting some business processing, we won’t be using our repository directly in the controller but we will proxy it through the PersonService .

As you can see we are not using any guice or javax dependency injection annotations here, we would need to wire things up manually. Before wiring though, we need a concrete implementation for our repository.

Note that we are still not bound to a specific effect, the only requirement we have, is that the effect we will use later implements the MonadError (we didn’t even have to do that but it’s much easier to deal with errors when we have that in place).

If you compare the above snippet to the first version of the repository discussed in Part 1 (todo: add link), you will see that we are no longer bound to the IO and we are using F[Person] , F[Option[Person] etc. On top of that, I have added one more method to get a Person from the database using the name argument — this will be used to show some useless business logic in the service layer.

Because we have resigned from using the built-in dependency injection mechanism available in Play, we need to configure our application loader by hand. This is much easier than it sounds and can be done directly with new or using some wring library like macwire (which I highly recommend as it’s created by one of our SoftwareMill’ers — Adam Warski).

I have created two separate component groups and load them with custom AppLoader :

The database specific dependencies are available in DatabaseComponents and used in more general AppComponents .

Please refer to the source code inside ‘ wiring ’ package for more information.

At this point we have abstracted our repository and service layer and we can decide which effectfull concrete implementation we will use when we wire the whole application up (in this case we picked IO ). As a bonus to our solution, we have defined that our effect should implement the algebra of MonadError which will help us further to deal with errors in our call stack.

For the full implementation of the presented solutions in example Play application please refer to the Github repository here.

Watch this space for more stuff regarding the Play framework and how to make it more FP.