如何使用 Circe 为 Either 类型创建解码器?
How to create a decoder for an Either type with Circe?
如果您希望收到类型为 A
或类型为 B
(Either[A, B]
) 的 Json,您如何为它编写解码器?
例如,假设您正在为外部 API 构建一个客户端,它可以用一些预期的 Json 结构来回答:
{
"fieldA": "value",
"fieldB": "value2"
}
或者如果出现问题,它将用一个带有 error
字段的对象来回答:
{
"error": "Your request was wrong"
}
然后你想要一个具有这些结构之一的实例:
val response: String = // Response from the server
val decodedValue =
decode[Either[ErrorResponse, ExpectedResponse](response) // (...) <- What implicit to place here?
如何为一种或另一种响应结构编写解码器?
从Circe issue 672开始,您可以通过以下方式为 Either 编写通用解码器:
implicit def eitherDecoder[A, B](implicit a: Decoder[A], b: Decoder[B]): Decoder[Either[A, B]] = {
val left: Decoder[Either[A, B]]= a.map(Left.apply)
val right: Decoder[Either[A, B]]= b.map(Right.apply)
left or right
}
注意:对于这种方法,您仍然需要为A
和B
隐式定义一个解码器。在大多数情况下,使用 deriveDecoder
就足够了。
如果您希望收到类型为 A
或类型为 B
(Either[A, B]
) 的 Json,您如何为它编写解码器?
例如,假设您正在为外部 API 构建一个客户端,它可以用一些预期的 Json 结构来回答:
{
"fieldA": "value",
"fieldB": "value2"
}
或者如果出现问题,它将用一个带有 error
字段的对象来回答:
{
"error": "Your request was wrong"
}
然后你想要一个具有这些结构之一的实例:
val response: String = // Response from the server
val decodedValue =
decode[Either[ErrorResponse, ExpectedResponse](response) // (...) <- What implicit to place here?
如何为一种或另一种响应结构编写解码器?
从Circe issue 672开始,您可以通过以下方式为 Either 编写通用解码器:
implicit def eitherDecoder[A, B](implicit a: Decoder[A], b: Decoder[B]): Decoder[Either[A, B]] = {
val left: Decoder[Either[A, B]]= a.map(Left.apply)
val right: Decoder[Either[A, B]]= b.map(Right.apply)
left or right
}
注意:对于这种方法,您仍然需要为A
和B
隐式定义一个解码器。在大多数情况下,使用 deriveDecoder
就足够了。