I use this library https://christopherdavenport.github.io/fuuid/ for creating ID
of custom object and persist them into databse.
I have a simple case class
which is my model:
import io.chrisdavenport.fuuid.FUUID
case class Bet(
betId: Option[FUUID],
home: String,
away: String,
stake: BigDecimal,
betType: String)
I used FUUID
here as an Option
parameter. I have also a routes
created with Http4s
which should take json from input and map it into model:
class BettingRoutes[F[_] : Async](service: BettingService[F]) extends Http4sDsl[F] {
def routes: HttpRoutes[F] = HttpRoutes.of[F] {
case req@PUT -> Root / "bets" =>
for {
bet <- req.as[Bet]
created <- service.put(bet)
response <- Created(created)
} yield response
}
}
I also added some implicits
to encode and decode from Circe
:
object jsons {
implicit def circeDecoder[A[_] : Sync, B: Decoder]: EntityDecoder[A, B] = jsonOf[A, B]
implicit def circeEncoder[A[_] : Sync, B: Encoder]: EntityEncoder[A, B] = jsonEncoderOf[A, B]
}
The problem is - when I want to compile project, I got an errors like this in route class:
Error:(23, 22) Cannot decode into a value of type model.Bet, because no EntityDecoder[F, model.Bet] instance could be found.
bet <- req.as[Bet]
Error:(23, 22) not enough arguments for method as: (implicit F: cats.Functor[F], implicit decoder: org.http4s.EntityDecoder[F,model.Bet])F[model.Bet].
Unspecified value parameter decoder.
bet <- req.as[Bet]
Error:(25, 28) Cannot convert from model.Bet to an Entity, because no EntityEncoder[F, model.Bet] instance could be found.
response <- Created(created)
etc. I investigated it and it appears because of using FUUID
. I changed all FUUID
classes to Long
and after this just to java's UUID
and then everything compile correctly without errors. The problem is only with FUUID
and probably with conversion of it. I tried to use Circe Integration
as It was shown in FUUID
link above, but it did not help. Do you know how to fix this code to compile everything with fuuid
and circe
?
I am new to cats
and connected libs, so maybe it is a simple mistake, but it is not trivial for me now.
In order to have EntityDecoder[F, Bet]
via jsons.circeDecoder
we firstly need Decoder[Bet]
. It can be auto-generated by Circe if we have decoders for all fields. The thing is there is Decoder[UUID]
but no Decoder[FUUID]
.
So just define necessary implicit
implicit val fuuidDecoder: Decoder[FUUID] = Decoder[UUID].map(FUUID.fromUUID)
Similarly for encoders
implicit val fuuidEncoder: Encoder[FUUID] = Encoder[UUID].contramap(FUUID.Unsafe.toUUID)