问题描述
试图编译这个对ZIO友好的Tapir / Http4s端点描述
import io.circe.generic.auto._
import org.http4s.HttpRoutes
import sttp.tapir.json.circe
import sttp.tapir.ztapir._
import sttp.tapir.server.http4s.ztapir._
import sttp.tapir.endpoint
import zio.RIO
import zio.interop.catz._
case class HealthReplyDTO(message: String)
final class HealthEndpointZTapir[E]() {
private val prefixPath = "/health"
val healthOkReply = HealthReplyDTO("OK")
private val routeDescription: ZEndpoint[Unit,Unit,HealthReplyDTO] =
endpoint.get.in(prefixPath).out(circe.jsonBody[HealthReplyDTO]).description("Health Endpoint")
val route: HttpRoutes[RIO[E,*]]
= routeDescription.toRoutes( _ => RIO.succeed(healthOkReply))
}
并保持在最后一行。
Type mismatch. Required: HttpRoutes[RIO[E,*]],found: HttpRoutes[zio.Task]
任务是RIO的子类型,所以应该可以正常工作吗?还是我在这里想念什么。 这个世界有点菜鸟,所以将不胜感激。
解决方法
Task
的确是RIO[R,*]
的子类型,但是来自http4s的HttpRoutes
是不变的,因此也显示错误消息。
由于与http4s集成(没有键入错误),因此.toRoutes
方法返回HttpRoutes[Task]
。通常,http4s在设置服务器和处理路由时会抛出任何类型的异常,因此我们需要使用Task
。
我终于结束了这样的事情。
编译器在最后一行需要一点帮助,在这行中隐式被证明是不够的。 tap的ztapir
部分已固定为ZIO效果类型Task
,因此在我的情况下无法使用
import io.circe.generic.auto._
import org.http4s.HttpRoutes
import sttp.tapir.json.circe
import sttp.tapir.server.http4s._
import sttp.tapir.endpoint
import zio.RIO
import zio.interop.catz._
import sttp.tapir._
final class HealthEndpointTapir[E]() extends TapirHttp4sServer {
private val prefixPath = "/health"
val healthOkReply: HealthReplyDTO = HealthReplyDTO("OK")
implicit val customServerOptions: Http4sServerOptions[RIO[E,*]] = Http4sServerOptions
.default[RIO[E,*]]
private val routeDescription: Endpoint[Unit,Unit,HealthReplyDTO,Any] =
endpoint.get.in(prefixPath).out(circe.jsonBody[HealthReplyDTO]).description("Health Endpoint")
val route: HttpRoutes[RIO[E,*]]
= RichHttp4sHttpEndpoint[Unit,RIO[E,*]
(routeDescription).toRoutes( _ => RIO.succeed(Right(healthOkReply)))
}