1

I'm using ZIO for the first time and I started with a boilerplate stub from https://github.com/guizmaii/scala-tapir-http4s-zio/blob/master/src/main/scala/example/HttpApp.scala that uses ZIO version 1.0.0-RC17 to set up and run an http4s Blaze server, including Tapir. That worked out nicely, but later on I tried to update to version 1.0.3 so that I'm using an up-to-date version, but that version is not compatible with the code in this stub. Specifically:

This is the code that defines the server (some unrelated routing lines cut out of the original):

val prog: ZIO[ZEnv, Throwable, Unit] = for {
  conf <- ZIO.effect(ApplicationConf.build().orThrow())
  _ <- putStrLn(conf.toString)
  server = ZIO.runtime[AppEnvironment].flatMap { implicit rts =>
    val apiRoutes = new ApiRoutes[AppEnvironment]()
    val allTapirRoutes                           = apiRoutes.getRoutes.foldK
    val httpApp: HttpApp[RIO[AppEnvironment, *]] = (allTapirRoutes).orNotFound
    val httpAppExtended = Logger.httpApp(logHeaders = true, logBody = true)(httpApp)
    BlazeServerBuilder[ZIO[AppEnvironment, Throwable, *]]
      .bindHttp(conf.port.port.value, conf.server.value)
      .withHttpApp(httpAppExtended)
      .withoutBanner
      .withSocketKeepAlive(true)
      .withTcpNoDelay(true)
      .serve
      .compile[RIO[AppEnvironment, *], RIO[AppEnvironment, *], ExitCode]
      .drain
  }
  prog <- server.provideSome[ZEnv] { currentEnv =>
    new Clock {
      override val clock: Clock.Service[Any] = currentEnv.clock
    }
  }
} yield prog

prog.foldM(h => putStrLn(h.toString).as(1), _ => ZIO.succeed(0))

This is the main body of the run() method. Running this code never results in the app exiting with code 0 because the Blaze server blocks termination, as expected. The problem is this snippet:

prog <- server.provideSome[ZEnv] { currentEnv =>
    new Clock {
      override val clock: Clock.Service[Any] = currentEnv.clock
    }
  }

This doesn't work in 1.0.3 because of the introduction of Has[A]. The compiler now complains that you can't inherit from final class Has so you can't invoke a new Clock.

I tried to remedy this by replacing it with

prog = server.provideSomeLayer[ZEnv]

and replacing the exit code ints with ExitCode objects, which made the code compile, but after this the Blaze server did not seem to initialize or prevent termination of the app. It just finished with exit code 0.

Clearly there's something missing here, and I haven't seen any information on the shift from the older environment system to the new system based on Has[A]. How can I fix this boilerplate so that the Blaze server runs again?

emote_control
  • 745
  • 6
  • 21

1 Answers1

0

If you are interested in a template tapir-zio-http4s project, I suggest using the one from tapir repo: https://github.com/softwaremill/tapir/blob/master/examples/src/main/scala/sttp/tapir/examples/ZioExampleHttp4sServer.scala

It is guaranteed to always compile against the latest Tapir (since it's a part of the project).

Also I personally used it recently. It worked.

simpadjo
  • 3,947
  • 1
  • 13
  • 38