首页 > 解决方案 > 貘, Circe, 图式

问题描述

我有一个这样的案例类

    case class OffboardingError1(
    userId: Option[String],
    error: OffboardingErrorType1
)

    object OffboardingError1 {
      implicit val encode: Encoder[OffboardingError1] = deriveEncoder[OffboardingError1]
      implicit val decode: Decoder[OffboardingError1] = deriveDecoder[OffboardingError1]
      implicit val codecJson: CodecJson[OffboardingError1] = CodecJson.derive[OffboardingError1]
      implicit val schema: Schema[OffboardingError1] = implicitly[Derived[Schema[OffboardingError1]]].value
    }

OffboardingErrorType1 定义如下:

trait OffboardingErrorType1 {
  val name: String
  val message: String
}

object OffboardingErrorType1 {
  case class UnknownError1(name: String = "UnknownError", message: String) extends OffboardingErrorType1
  case class S3ImageFindError1(name: String = "S3ImageFindError", message: String) extends OffboardingErrorType1

  def getErrorTypeFromString(name: String, errorMessage: String): Option[OffboardingErrorType1] = name match {
    case "UnknownError" => Some(UnknownError1(message = errorMessage))
    case "S3ImageFindError" => Some(S3ImageFindError1(message = errorMessage))
    case _ => None
  }

  implicit val encoder: Encoder[OffboardingErrorType1] = {
    (offBoardingTypeError: OffboardingErrorType1) =>
      Json.obj(
        ("name", offBoardingTypeError.name.asJson),
        ("message", offBoardingTypeError.message.asJson)
      )
  }

  implicit val decoder: Decoder[OffboardingErrorType1] = {
    c =>
      for {
        name <- c.downField("name").as[String]
        errorMessage <- c.downField("message").as[String]
      } yield getErrorTypeFromString(name, errorMessage) match {
        case Some(cType) => cType
        case _ => throw new IllegalArgumentException(s"bad name for offboarding error type: [${name}]")
      }
  }
  implicit val codec: CodecJson[OffboardingErrorType1] = {
    import argonaut._
    import Argonaut._
    CodecJson(
      (errorType: OffboardingErrorType1) =>
        ("name" := errorType.name) ->:
          ("message" := errorType.message) ->:
          jEmptyObject,
      c => for {
        name <- c.downField("name").as[String]
        message <- c.downField("message").as[String]
        result <- getErrorTypeFromString(name, message).fold(
          DecodeResult.fail[OffboardingErrorType1](s"bad name for offboarding error type: [${name}]", CursorHistory.empty)
        )(DecodeResult.ok)
      } yield result
    )
  }
}

我正在使用tap作为端点,代码是这样的

val coursePlanCreationJob: Endpoint[(String, CoursePlanCreationRequest), ServiceThrowable, JobInfo1, Nothing] =
    V1Endpoint.v1Endpoint
      .post
      .description("create a coursePlan")
      .in("courses" / "type" / "create-courseplan")
      .in(jsonBody[CoursePlanCreationRequest])
      .out(jsonBody[OffboardingError1])

设置编译给我错误找不到参数 e 的隐式值:sttp.tapir.generic.Derived[sttp.tapir.Schema[io.ctek.services.palpatine.model.response.OffboardingError1]] [error] 隐式 val 架构: Schema[OffboardingError1] = implicitly[Derived[Schema[OffboardingError1]]].value 我猜这是因为“OffboardingErrorType1”特性。任何人都知道如何为这种类型的特征编写模式?

标签: scalacircetapir

解决方案


推荐阅读