Bringing it all together

The server code will require a few new imports in addition to our usual set:

import org.http4s.server.blaze.BlazeBuilder
import scala.concurrent.ExecutionContext.Implicits.global

BlazeBuilder is a server factory, and ExecutionContext will be needed at the moment we start the server. The server is defined as follows:

object Server extends StreamApp[IO] { ... }

StreamApp requires us to implement a stream method, with the solely purpose to produce side-effects and provides cleanup hooks for this stream. This is our implementation:

override def stream(args: List[String],
requestShutdown: IO[Unit]): Stream[IO, ExitCode] = {
val config: IO[Config] = Config.load("application.conf")
new ServerInstance(config).create().flatMap(_.serve)
}

We just read the configuration and delegate the actual server creation to ServerInstance. Let's have a look at it:

class ServerInstance(config: IO[Config]) {
def create(): Stream[IO, BlazeBuilder[IO]] = {
for {
config <- Stream.eval(config)
transactor <- Stream.eval(DB.transactor(config.database))
_ <- Stream.eval(DB.initialize(transactor))
} yield BlazeBuilder[IO]
.bindHttp(config.server.port, config.server.host)
.mountService(new Service(new Repository(transactor)).service, "/")
}
}

Here again we see the same approach: we lift config into the context of Stream, create a transactor, initialize the database, build the repository from the transactor and the service from the repository, and finally mount the service by using the BlazeBuilder factory.

The caller method will then execute the serve method of the server, starting the whole IO program we've built so far. 

We were following a pattern for providing dependencies as we've build up this example—we gave them as constructor parameters at the moment we constructed class instances. The approach of passing dependencies as constructor parameters is called constructor-based dependency-injection in Scala.

Now our application can be started and played with. But we want to be sure that it behaves correctly by testing it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.224.226