在以下情况下,我需要一些帮助。我有一个带有注册请求的 JSON API。该请求采用 4 个参数:标准电话、密码、电子邮件和客户选择类型的人员参数。根据选择的类型,他们必须再指定一个参数:姓名或年龄。
当我收到一个 HTTP 请求时,我需要将它解码为我的请求对象。使用以下代码执行此操作会导致以下类型的编译错误:
type mismatch;
found : Unit
required: io.circe.Decoder[RegistrationReq]
任何想法为什么会出现这种情况以及如何解决它?提前致谢!
import cats.effect.Sync
import cats.syntax.either._
import circe.jsonOf
import io.circe.{Decoder, DecodingFailure, HCursor}
import io.circe.generic.semiauto._
import io.circe.refined._
import io.circe.Decoder.Result
import org.http4s.EntityDecoder
trait RegJsonCodec {
import JsonCodec._ //all common encoders and decoders come from there
implicit val RegistrationReqDecoder: Decoder[RegistrationReq] = {
def apply(c: HCursor): Result[RegistrationReq] =
for {
phone <- getPhone(c)
password <- c.downField("password").as[Password]
email <- c.downField("email").as[Email] //Password and Email are refined Strings
person <- getPerson(c)
} yield RegistrationReq(phone, password, email, person)
}
private def getPhone(c: HCursor): Either[DecodingFailure, Long] =
c.downField("phone").as[Long].orElse {
c.downField("phone").as[String].flatMap {
str =>
Either.catchNonFatal(str.toLong)
.leftMap(e => DecodingFailure(e.getMessage, c.history))
}
}.flatMap(phone => Either.right(phone))
private def getPerson(c: HCursor): Either[DecodingFailure, Person] = {
c.downField("person").downField("type").as[String].flatMap { type =>
c.downField("person").downField("name").as[String]
.orElse(c.downField("person").downField("age").as[String]).flatMap { extra =>
Either.catchNonFatal(Person.fromPair(type, extra))
.leftMap(e => DecodingFailure(e.getMessage, c.history))
.flatMap(person => Either.right(person))
}
}
}
implicit def requestEntityDecoder[F[_] : Sync]: EntityDecoder[F, RegistrationReq] = jsonOf[F, RegistrationReq]
}
object RegJsonCodec extends RegJsonCodec