Проблема компиляции между HttpRoutes [RIO [E, *]] и HttpRoutes [zio.Task]
Попытка скомпилировать это небольшое описание конечной точки, дружественного к 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, так что все должно работать нормально? Или мне что-то здесь не хватает. Немного новичок в этом мире, так что некоторая помощь будет очень признательна.
2 ответа
Task
действительно является подтипом
RIO[R, *]
, но
HttpRoutes
from http4s инвариантно, а значит, и сообщение об ошибке.
В
.toRoutes
метод возвращает
HttpRoutes[Task]
как следствие интеграции с http4s, в котором нет типизированных ошибок. В общем, http4s может генерировать исключения любого типа при настройке сервера и обработке маршрутов, поэтому нам нужно работать с
Task
.
В конце концов, я сделал что-то подобное. Компилятору нужна небольшая помощь в последней строке, где имплицитов оказалось недостаточно. В
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, Unit, HealthReplyDTO, RIO[E, *]
(routeDescription).toRoutes( _ => RIO.succeed(Right(healthOkReply)))
}