Last active
June 2, 2020 09:24
-
-
Save adamw/12fcda4602d45d24a0de02922c3d775c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sttp.tapir.examples | |
import cats.arrow.FunctionK | |
import cats.data.OptionT | |
import izumi.reflect.Tag | |
import org.http4s._ | |
import org.http4s.server.Router | |
import org.http4s.server.blaze.BlazeServerBuilder | |
import org.http4s.syntax.kleisli._ | |
import zio.interop.catz._ | |
import zio.{Has, RIO, Runtime, ZIO, ZLayer} | |
import org.http4s.dsl.Http4sDsl | |
import zio.clock.Clock | |
import zio.random.Random | |
object ZioExampleHttp4sServer2 extends App { | |
type EffLocal[X] = RIO[Has[Int] with Has[String], X] | |
val dsl = Http4sDsl[EffLocal] | |
import dsl._ | |
def logic(name: String): EffLocal[String] = | |
for { | |
v1 <- RIO.access[Has[Int]](_.get) | |
v2 <- RIO.access[Has[String]](_.get) | |
} yield s"Hello, $name ($v1, $v2)." | |
val service: HttpRoutes[EffLocal] = HttpRoutes.of[EffLocal] { | |
case GET -> Root / "hello" / name => Ok(logic(name)) | |
} | |
type EffEnv = Random with Clock with Has[Int] with Has[String] | |
type Eff[X] = RIO[EffEnv, X] | |
val serviceAll: ZIO[Random with Clock, Nothing, HttpRoutes[Eff]] = | |
Translate[Random with Clock, Has[Int] with Has[String]](service) | |
val program: Eff[Unit] = ZIO.runtime[EffEnv].flatMap { implicit runtime => | |
serviceAll.flatMap { sa => | |
BlazeServerBuilder[Eff](runtime.platform.executor.asEC)(taskEffectInstance[EffEnv], zioTimer) | |
.bindHttp(8080, "localhost") | |
.withHttpApp(Router("/" -> sa).orNotFound) | |
.serve | |
.compile | |
.drain | |
} | |
} | |
Runtime.default.unsafeRun(program.provideLayer(Random.live ++ Clock.live ++ ZLayer.succeed(42) ++ ZLayer.succeed("x"))) | |
} | |
object Translate { | |
def apply[R0 <: Has[_], R1 <: Has[_]: Tag]( | |
baseService: HttpRoutes[RIO[R1, *]] | |
): ZIO[R0, Nothing, HttpRoutes[RIO[R0 with R1, *]]] = { | |
type Eff1[X] = RIO[R1, X] | |
type Eff2[X] = RIO[R0 with R1, X] | |
val eff1ToEff2 = new FunctionK[Eff1, Eff2] { | |
override def apply[A](fa: Eff1[A]): Eff2[A] = fa | |
} | |
def eff2ToEff1(r0: R0) = | |
new FunctionK[Eff2, Eff1] { | |
override def apply[A](fa: Eff2[A]): Eff1[A] = fa.provideSome[R1](r0.union[R1](_)) | |
} | |
ZIO.access[R0] { r0 => | |
baseService | |
.mapK(new FunctionK[OptionT[Eff1, *], OptionT[Eff2, *]] { | |
override def apply[A](fa: OptionT[Eff1, A]): OptionT[Eff2, A] = fa.mapK(eff1ToEff2) | |
}) | |
.dimap[Request[Eff2], Response[Eff2]](_.mapK(eff2ToEff1(r0)))(_.mapK(eff1ToEff2)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment