我使用这个库https://christopherdavenport.github.io/fuuid/来创建自定义对象的ID
并将它们保存到数据库中。我有一个简单的case class
,这是我的模型:
import io.chrisdavenport.fuuid.FUUID
case class Bet(
betId: Option[FUUID],
home: String,
away: String,
stake: BigDecimal,
betType: String)
我在这里使用FUUID
作为Option
参数。我还有一个用routes
创建的Http4s
,它应该从输入中获取json并将其映射到模型中:
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
}
}
我还添加了一些implicits
来编码和解码来自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]
}
问题是 - 当我想编译项目时,我在路由类中遇到了这样的错误:
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)
我调查了它,因为使用FUUID
而出现。我将所有FUUID
类更改为Long
,然后将其更改为java的UUID
,然后所有内容都正确编译而没有错误。问题只出在FUUID
上,可能还有转换它。我尝试使用Circe Integration
,因为它在上面的FUUID
链接中显示,但它没有帮助。你知道怎么修这个代码用fuuid
和circe
编译所有东西吗?我是cats
和连接库的新手,所以也许这是一个简单的错误,但现在对我来说并不是微不足道的。
为了通过EntityDecoder[F, Bet]
获得jsons.circeDecoder
,我们首先需要Decoder[Bet]
。如果我们有所有字段的解码器,它可以由Circe自动生成。事情是有Decoder[UUID]
但没有Decoder[FUUID]
。
所以只需定义必要的隐含
implicit val fuuidDecoder: Decoder[FUUID] = Decoder[UUID].map(FUUID.fromUUID)
同样适用于编码器
implicit val fuuidEncoder: Encoder[FUUID] = Encoder[UUID].contramap(FUUID.Unsafe.toUUID)