Play Framework integration

Freestyle programs are easy to use as a result of a Play Framework Action with the freestyle-http-play module. This module provides an implicit conversion FreeS[F, A] => Future[A] which allows a user to define a Free program as the result of any Play Action that expects a Future as a response.

To enable this integration you can depend on freestyle-http-play with Play framework 2.6:

libraryDependencies += "io.frees" %% "frees-play" % "0.8.2"

The regular imports for working with Freestyle and Cats:

import cats.implicits._

And some imports for the frees-http-play module and Play itself:


import javax.inject._

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

import scala.concurrent.ExecutionContext

import{ActorMaterializer, Materializer}

For demonstration purposes, we will create a very simple program that returns an OK http status response:

// import

object algebras {
  trait Noop {
    def ok: FS[String]
// defined object algebras
import cats.Monad
// import cats.Monad

object handlers {
  import algebras._

  implicit def noopHandler[M[_]](
      implicit MM: Monad[M]
  ): Noop.Handler[M] = new Noop.Handler[M] {
    def ok: M[String] = MM.pure("success!")
// defined object handlers
import algebras._
// import algebras._

import handlers._
// import handlers._

def program[F[_]: Noop]: FreeS[F, Result] =
  for {
    msg <- Noop[F].ok
  } yield Results.Ok(msg)
// program: [F[_]](implicit evidence$1: algebras.Noop[F])[F,play.api.mvc.Result]

Once our program is defined we may simply return it as a result of any Action without the need to explicitly interpret it to Future:

class AppController @Inject()(val controllerComponents: ControllerComponents)(implicit ec: ExecutionContext) extends BaseController {
  def endpoint = Action.async { _ => program[Noop.Op] }