scala - 貘自定义编解码器

标签 scala codec circe

我被困在一个地方,我正在使用 scala、tapir 和 circe。

sealed abstract class S1Error extends Product with Serializable
object S1Error {
  final case class SError(error: SMError) extends S1Error
}
sealed abstract class SMError(message: String)
object SMError {
  final case class SVError(message: String) extends SMError(message)
}

对于貘 errorOut,我正在使用这个

val schemaVersionError: EndpointOutput.StatusMapping[SError] = statusMappingValueMatcher(
      StatusCode.BadRequest,
      jsonBody[SError]
        .description("XXXX.")
    ) {
      case SMError(SVError(_)) => true
      case _                                  => false
    }

现在因为这个结构,我得到的API结果是

{
    "error": {
        "SVError": {
            "message": "XXXXG"
        }
    }
}

理想情况下,我希望响应为

"message": "XXXXG"

我无法更改错误结构。 有没有一种方法可以使用自定义编解码器来包装此错误以根据需要获得结果。

最佳答案

Tapir 编解码器源自 Circe 的解码器和编码器。

您看到的是 circe 编码案例类的默认方式。

Circe 提供了按照您使用来自 circe-generic-extrasderiveUnwrappedEncoder 描述的方式对案例类进行编码的可能性。 .不幸的是,它不会针对 SMError 进行编译(可能派生机制被您的抽象类层次结构搞糊涂了)。

您可以做的只是手动创建编码器:

sealed abstract class S1Error extends Product with Serializable

object S1Error {
  final case class SError(error: SMError) extends S1Error

  implicit val encoder: Encoder[SError] = Encoder[SMError].contramap(_.error)
  // or you can use deriveUnwrappedEncoder from circe-generic-extras:
  // implicit val encoder: Encoder[SError] = deriveUnwrappedEncoder
}

//I also needed to make message a field in SMError
sealed abstract class SMError(val message: String)
object SMError {
  final case class SVError(override val message: String) extends SMError(message)

  implicit val encoder: Encoder[SMError] = Encoder.encodeJsonObject.contramap{s => JsonObject("message" -> s.message.asJson)}
}

响应现在看起来像:

{
    message": "XXXXG"
}

关于scala - 貘自定义编解码器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60709580/

相关文章:

scala - Slick 2.1.0 GroupBy 并获取所有列

scala - sbt 执行期间出错 : java. lang.NoClassDefFoundError: scala/StringContext

java - 如何从文件系统中获取文件属性流?

scala - 用于编码/解码 arity 0 的密封特征实例的 Circe 实例?

scala - 使用带有一些基类、抽象类或特征参数化列表的类型类的最佳方法

audio - 一种将数据 "mid stream"添加到编码音频的方法(可能使用 AAC)

file - 新的音频文件格式

json - 将 circe 中 json 对象的所有键从 `underscore` 转换为 `camel case`

scala - 当字段不完整时用 Circe 解码 Json

c++ - Fourcc 与 mac os X