貘自定义编解码器
Tapir Custom Codec
我被困在一个地方,我正在使用 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 的解码器和编码器。
你看到的是默认的大小写编码方式classes by circe。
Circe 提供了编码大小写 classes 的可能性,就像您使用 circe-generic-extras 中的 deriveUnwrappedEncoder
描述的那样。不幸的是,它没有为 SMError
编译(可能派生机制被你的抽象 class 层次结构混淆了)。
您可以做的只是手动创建编码器:
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、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 的解码器和编码器。
你看到的是默认的大小写编码方式classes by circe。
Circe 提供了编码大小写 classes 的可能性,就像您使用 circe-generic-extras 中的 deriveUnwrappedEncoder
描述的那样。不幸的是,它没有为 SMError
编译(可能派生机制被你的抽象 class 层次结构混淆了)。
您可以做的只是手动创建编码器:
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"
}