I have created HttpRoutes for ZIO app
class BlockChainAPI[R <: BlockChain] {
type BlockChainTask[A] = RIO[R, A]
private val dsl = Http4sDsl[BlockChainTask]
import dsl._
implicit def jsonDecoder[A](implicit decoder: Decoder[A]): EntityDecoder[BlockChainTask, A] = jsonOf[BlockChainTask, A]
implicit def jsonEncoder[A](implicit encoder: Encoder[A]): EntityEncoder[BlockChainTask, A] = jsonEncoderOf[BlockChainTask, A]
val routes: HttpRoutes[BlockChainTask] = HttpRoutes.of[BlockChainTask] {
case GET -> Root / "message" / message =>
val newMessage = BlockMessage(message)
BlockChain
.addBlock(Seq(newMessage))
.foldZIO(
err => BadRequest(err.getMessage),
_ => Ok(s"Message $message added")
)
}
}
and it works fine! But today I've added a new route:
case GET -> Root =>
StaticFile.fromPath(fs2.io.file.Path("/api-docs/index.html")).getOrElse(NotFound()).foldZIO(
err => InternalServerError(err.getMessage),
result => Ok(result)
)
and it fails with error: Cannot convert from Product with java.io.Serializable to an Entity, because no EntityEncoder[[A]zio.ZIO[R,Throwable,A], Product with java.io.Serializable] instance could be found.
Maybe someone knows how to fix it?!
I added:
implicit def jsonEncoder2[A <: Product with Serializable](implicit encoder: Encoder[A]): EntityEncoder[BlockChainTask, A] = jsonEncoderOf[BlockChainTask, A]
but it doesn't work
Your
result
has aProduct with Serializable
type, which is not something http4s knows how to encode it in the HTTP response.This is because
StaticFile.fromPath(fs2.io.file.Path("/api-docs/index.html")).getOrElse(NotFound())
actually gives you 2 unrelated types depending on whether you go through the nominal path or thegetOrElse
path.You need to return a consistent type in both paths, or don't use
getOrElse
at this stage, or move the missing case to the error channel.Using intermediate variables with explicit types should help you.